From 50172f8ba7b8b5672abcf4319687855d2ab26356 Mon Sep 17 00:00:00 2001 From: chanduy-jannu Date: Sat, 8 Aug 2026 10:08:37 +0530 Subject: [PATCH 1/3] Add localhost-3000 hackathon submission --- .../skills/mutagent-agentspec/CLAUDE.md | 33 + .../skills/mutagent-agentspec/SKILL.md | 138 + .../agentspec.decisions.md | 33 + .../agent-support-triage/agentspec.yaml | 187 + .../agentspec.yaml | 185 + .../skill-release-brief/agentspec.yaml | 114 + .../workflow-incident-routing/agentspec.yaml | 117 + .../assets/templates/agentspec.yaml.tpl | 93 + .../references/agentspec-0.3-field-catalog.md | 136 + .../references/frameworks/doc-pins.md | 53 + .../references/principles.md | 96 + .../references/requirements.yaml | 305 ++ .../workflows/orchestrator-protocol.md | 396 ++ .../mutagent-agentspec/scripts/cli/doctor.ts | 116 + .../mutagent-agentspec/scripts/cli/init.ts | 230 + .../mutagent-agentspec/scripts/cli/run.sh | 72 + .../scripts/config/resolve-spec-dir.ts | 199 + .../scripts/contract/agentspec.schema.ts | 830 ++++ .../scripts/lib/entrypoint.ts | 41 + .../scripts/setup/detect.ts | 67 + .../scripts/template/slot-checklist.ts | 175 + .../scripts/validate/semantic-validator.ts | 452 ++ .../scripts/validate/validate-spec.ts | 127 + .../.agents/skills/mutagent-builder/SKILL.md | 100 + .../assets/agents/ai-architect.md | 383 ++ .../assets/agents/ai-engineer.md | 373 ++ .../assets/fixtures/plan-only/build-report.md | 54 + .../assets/templates/build-report.md.tpl | 79 + .../mutagent-builder/references/principles.md | 18 + .../references/workflows/build-protocol.md | 121 + .../references/workflows/optimize-handoff.md | 23 + .../mutagent-builder/scripts/cli/run.sh | 72 + .../scripts/handoff/validate-build-input.ts | 76 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/sync-spec/check-sync-spec.ts | 524 +++ .../scripts/verify/spec-impl-coverage.ts | 185 + .../skills/mutagent-diagnostics/README.md | 192 + .../skills/mutagent-diagnostics/SKILL.md | 362 ++ .../assets/agents/diagnostics-analyzer.md | 636 +++ .../assets/templates/audit.json.tpl | 24 + .../assets/templates/audit.md.tpl | 49 + .../assets/templates/config.yaml.tpl | 100 + .../assets/templates/pr-body.md.tpl | 56 + .../assets/templates/report.html.tpl | 390 ++ .../assets/templates/shared/README.md | 27 + .../templates/shared/iter-N-handover.md.tpl | 125 + .../self-diagnosis-contract.v0.1.0.yaml.tpl | 234 + .../assets/templates/shared/spec.yaml.tpl | 152 + .../assets/templates/shared/team.yaml.tpl | 127 + .../shared/wave-N-dashboard.html.tpl | 1712 ++++++++ .../wireframes/diagnostics/WF-2.1-nl-query.md | 59 + .../diagnostics/WF-2.2-tier0-progress.md | 58 + .../diagnostics/WF-2.3-analysis-progress.md | 44 + .../diagnostics/WF-2.4-html-report.md | 61 + .../diagnostics/WF-2.5-rca-detail.md | 69 + .../diagnostics/WF-2.6-stale-warning.md | 53 + .../wireframes/onboarding/WF-1.1-welcome.md | 60 + .../WF-1.2-source-platform-picker.md | 41 + .../onboarding/WF-1.3-source-auth.md | 75 + .../onboarding/WF-1.4-target-picker.md | 48 + .../wireframes/onboarding/WF-1.5-ask-tool.md | 43 + .../onboarding/WF-1.6-config-review.md | 57 + .../onboarding/WF-1.7-filter-defaults.md | 52 + .../wireframes/onboarding/WF-1.8-first-run.md | 59 + .../examples/sample-findings.json | 92 + .../examples/sample-meta.json | 47 + .../references/adapter-strategy.md | 75 + .../references/config-migration.md | 93 + .../mutagent-diagnostics/references/config.md | 159 + .../references/filter-search-matrix.md | 66 + .../references/harness-knowledge.md | 22 + .../references/memory-format.md | 78 + .../references/onboarding-decisions.yaml | 187 + .../references/operation-inventory.md | 59 + .../references/overview.md | 167 + .../references/reference.md | 124 + .../references/script-index.md | 101 + .../references/source-adapter-contract.md | 93 + .../claude-code-transcripts.md | 66 + .../source-platforms/codex-transcripts.md | 78 + .../references/source-platforms/codex.md | 145 + .../source-platforms/install-paths.md | 57 + .../references/source-platforms/langfuse.md | 178 + .../source-platforms/local-jsonl.md | 55 + .../source-platforms/openobserve.md | 102 + .../references/source-platforms/otel.md | 63 + .../references/target-platforms/cloud-rest.md | 84 + .../target-platforms/local-claude.md | 65 + .../target-platforms/local-cloud-agent-sdk.md | 92 + .../target-platforms/local-codex.md | 72 + .../target-platforms/local-cursor.md | 108 + .../target-platforms/local-mastra.md | 77 + .../target-platforms/local-opencode.md | 70 + .../workflows/apply-pr-comment-format.md | 82 + .../references/workflows/diagnostics.md | 35 + .../references/workflows/handover-contract.md | 247 ++ .../references/workflows/onboarding.md | 314 ++ .../workflows/orchestrator-protocol.md | 1933 +++++++++ .../references/workflows/rca.md | 331 ++ .../references/workflows/rendering-anatomy.md | 314 ++ .../references/workflows/schedule-prep.md | 100 + .../references/workflows/scope-model.md | 128 + .../workflows/verification-methodology.md | 174 + .../scripts/aggregate/sort-findings.ts | Bin 0 -> 5084 bytes .../scripts/awareness/blind-spots.ts | 168 + .../scripts/awareness/llm-sample.ts | 682 +++ .../scripts/cli/doctor.ts | 369 ++ .../mutagent-diagnostics/scripts/cli/init.ts | 1057 +++++ .../scripts/cli/install-agents.ts | 374 ++ .../mutagent-diagnostics/scripts/cli/run.sh | 73 + .../scripts/cli/runtime-deps.ts | 296 ++ .../scripts/cli/shared-templates.ts | 79 + .../scripts/config/load.ts | 400 ++ .../scripts/config/resolve-credential.ts | 120 + .../scripts/config/schema.ts | 692 +++ .../scripts/config/validate.ts | 140 + .../scripts/config/write.ts | 166 + .../context/build-diagnosis-context.ts | 418 ++ .../scripts/context/load-context.ts | 106 + .../scripts/contract/types.ts | 166 + .../scripts/enrich/build-render-input.ts | 2081 +++++++++ .../scripts/enrich/corpus-severity.ts | 172 + .../scripts/enrich/dismissal-match.ts | 270 ++ .../scripts/enrich/rank-remedies.ts | 176 + .../scripts/hooks/install-hooks.sh | 46 + .../scripts/hooks/pre-push.sh | 78 + .../scripts/invocation/parse-brief.ts | 190 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/library/match.ts | 114 + .../scripts/library/paths.ts | 95 + .../scripts/library/store.ts | 536 +++ .../scripts/library/types.ts | 181 + .../scripts/lint/template-inline-js.ts | 268 ++ .../scripts/memory/append.ts | 189 + .../scripts/memory/read.ts | 219 + .../normalize/platforms/entity-context.ts | 686 +++ .../scripts/normalize/read-unitf.ts | 668 +++ .../scripts/normalize/trace.ts | 1195 ++++++ .../scripts/normalize/unitf-adapter.ts | Bin 0 -> 16563 bytes .../scripts/normalize/unitf-types.ts | 213 + .../scripts/report/persist-selections.ts | 175 + .../scripts/report/render.ts | 3534 ++++++++++++++++ .../scripts/run/diagnose.ts | 65 + .../scripts/run/session.ts | 168 + .../scripts/sample/caps.ts | 347 ++ .../scripts/sample/deep-read-gate.ts | 461 ++ .../scripts/sample/representative.ts | 585 +++ .../scripts/scan/objection.ts | 224 + .../scripts/scan/trajectory.ts | 492 +++ .../scripts/self-diagnostics/dispatch.ts | 136 + .../scripts/self-diagnostics/probe.ts | 171 + .../scripts/setup/detect.ts | 345 ++ .../scripts/setup/ensure-cli.ts | 315 ++ .../scripts/setup/reconfigure.ts | 78 + .../scripts/setup/verify-agents.ts | 208 + .../mutagent-diagnostics/scripts/slicer.ts | 167 + .../scripts/source/adapters/claude-code.ts | 17 + .../scripts/source/adapters/codex.ts | 11 + .../scripts/source/adapters/langfuse.ts | 17 + .../scripts/source/adapters/local-jsonl.ts | 12 + .../scripts/source/adapters/otel.ts | 12 + .../scripts/source/index.ts | 54 + .../scripts/source/registry.ts | 45 + .../scripts/source/types.ts | 86 + .../scripts/stale-detector.ts | 75 + .../scripts/test/render-playwright.cli.ts | 477 +++ .../scripts/tier0-scan.ts | 431 ++ .../scripts/tier0/claude-code.ts | 139 + .../scripts/tier0/langfuse.ts | 149 + .../scripts/validate/completeness-check.ts | 437 ++ .../scripts/validate/doc-refs.ts | 191 + .../scripts/validate/finalize-gate.ts | 418 ++ .../scripts/validate/findings-contract.ts | 643 +++ .../scripts/validate/render-js-syntax.ts | 190 + .../scripts/validate/report-checklist.yaml | 217 + .../scripts/validate/trace-shape.ts | 263 ++ .../scripts/validate/wave6-checklist.ts | 327 ++ .../skills/mutagent-evaluator/SKILL.md | 548 +++ .../assets/agents/audit-executor.md | 169 + .../assets/agents/dataset-builder.md | 161 + .../assets/agents/evaluator.md | 1192 ++++++ .../mutagent-evaluator/assets/brand/theme.css | 213 + .../assets/brand/wordmark.html | 9 + .../assets/code-quality-criteria.yaml | 75 + .../templates/discover-report.template.html | 397 ++ .../templates/eval-report.template.html | 594 +++ .../templates/review-report.template.html | 560 +++ .../golden/judge-trajectory.prose.md | 90 + .../lenses/context-flow-lens.md | 85 + .../mutagent-evaluator/lenses/data-lens.md | 47 + .../lenses/decision-lens.md | 48 + .../lenses/methodology-critic-lens.md | 53 + .../lenses/trajectory-lens.md | 44 + .../references/build-review-interface.md | 83 + .../references/data-registry.md | 43 + .../mutagent-evaluator/references/edd-loop.md | 134 + .../references/error-analysis.md | 113 + .../references/eval-audit.md | 154 + .../references/eval-layers.md | 106 + .../references/eval-stage.md | 201 + .../references/generate-synthetic-data.md | 81 + .../references/grounded-adjudication.md | 221 + .../references/handoff-format.md | 89 + .../references/memory-format.md | 65 + .../references/methodology.md | 201 + .../references/operation-inventory.md | 197 + .../references/validate-evaluator.md | 125 + .../workflows/orchestrator-protocol.md | 319 ++ .../references/write-judge-prompt.md | 123 + .../schemas/behavior-tree.schema.yaml | 73 + .../schemas/dataset.schema.yaml | 66 + .../schemas/edd-change-request.schema.yaml | 114 + .../schemas/eval-matrix.schema.yaml | 74 + .../schemas/flow-graph.schema.yaml | 69 + .../schemas/flow-profile.schema.yaml | 49 + .../schemas/methodology-review.schema.yaml | 40 + .../schemas/scorecard.schema.yaml | 112 + .../scripts/agent-dispatch.ts | Bin 0 -> 10781 bytes .../scripts/aggregate-discover.ts | 881 ++++ .../scripts/apply-rulings.ts | 245 ++ .../scripts/artifact-paths.ts | 115 + .../scripts/assemble-scorecard.ts | 172 + .../mutagent-evaluator/scripts/audience.ts | 84 + .../scripts/build-dataset.ts | 186 + .../mutagent-evaluator/scripts/build-evals.ts | 93 + .../scripts/build-review-ui.ts | 707 ++++ .../scripts/check-method-router.ts | 170 + .../scripts/cli/aggregate.ts | 112 + .../scripts/cli/audit-run.ts | 182 + .../mutagent-evaluator/scripts/cli/doctor.ts | 212 + .../mutagent-evaluator/scripts/cli/dogfood.ts | 133 + .../mutagent-evaluator/scripts/cli/init.ts | 646 +++ .../scripts/cli/methodology-review.ts | 122 + .../mutagent-evaluator/scripts/cli/prep.ts | 325 ++ .../scripts/cli/profile-subject.ts | 165 + .../mutagent-evaluator/scripts/cli/run.sh | 68 + .../scripts/cli/runtime-deps.ts | 298 ++ .../scripts/cli/variance-check.ts | 105 + .../scripts/code-eval-library.ts | 285 ++ .../mutagent-evaluator/scripts/code-eval.ts | 248 ++ .../scripts/code-quality-verdict.ts | 277 ++ .../scripts/codegen-evals.ts | 173 + .../scripts/cold-start-project.ts | 151 + .../scripts/cold-start-sampler.ts | 267 ++ .../mutagent-evaluator/scripts/config/load.ts | 343 ++ .../scripts/config/schema.ts | 380 ++ .../scripts/contracts/agentspec-evals.ts | 147 + .../scripts/contracts/dataset.ts | 149 + .../scripts/contracts/eval-engine.ts | 118 + .../scripts/contracts/eval-matrix.ts | 916 ++++ .../scripts/contracts/eval-types.ts | 1125 +++++ .../scripts/contracts/flow-graph.ts | 194 + .../scripts/contracts/types.ts | 303 ++ .../scripts/contracts/validation.ts | 193 + .../scripts/criterion-identity.ts | 267 ++ .../scripts/decisions-store.ts | 265 ++ .../scripts/derive-dataset.ts | 152 + .../scripts/determine-outcome.ts | 227 + .../scripts/diff-discriminate.ts | 160 + .../scripts/discover-criteria.ts | 348 ++ .../scripts/edd/change-request.ts | 232 + .../scripts/edd/edd-types.ts | 210 + .../scripts/edd/variance-gate.ts | 186 + .../scripts/emit-completeness.ts | 111 + .../mutagent-evaluator/scripts/eval-engine.ts | 160 + .../mutagent-evaluator/scripts/evaluate.ts | 333 ++ .../mutagent-evaluator/scripts/flow-graph.ts | 230 + .../scripts/judge-prompt-template.ts | 382 ++ .../scripts/judge-provider.ts | 135 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/lint-grounding.ts | 229 + .../scripts/lint-uniformity.ts | 168 + .../scripts/living-suite.ts | 109 + .../mutagent-evaluator/scripts/load-bundle.ts | 203 + .../scripts/load-profile-vocab.ts | 64 + .../scripts/load-profile.ts | 106 + .../skills/mutagent-evaluator/scripts/mask.ts | 139 + .../scripts/materialize-dataset.ts | 175 + .../scripts/matrix-judge.ts | 1070 +++++ .../scripts/memory/append.ts | 215 + .../scripts/memory/ratify.ts | 165 + .../mutagent-evaluator/scripts/memory/read.ts | 168 + .../scripts/merge-criteria.ts | 887 ++++ .../scripts/persist-eval-criteria.ts | 232 + .../mutagent-evaluator/scripts/prep-tasks.ts | 136 + .../scripts/profile-subject.ts | 310 ++ .../scripts/publish-report.ts | 132 + .../scripts/read-manifest.ts | 120 + .../scripts/read-unitf-traces.ts | 113 + .../scripts/render-build-cards.ts | 232 + .../scripts/render-discover-report-v3.ts | 1242 ++++++ .../scripts/render-discover-report.ts | 1640 +++++++ .../scripts/render-eval-report-v3.ts | 743 ++++ .../scripts/render-eval-report.ts | 3757 +++++++++++++++++ .../scripts/render-report.ts | 212 + .../scripts/render-review-report-v3.ts | 720 ++++ .../scripts/report-fragments.ts | 173 + .../scripts/resolve-credential.ts | 110 + .../mutagent-evaluator/scripts/resolve-ref.ts | 98 + .../scripts/result-verify.ts | 129 + .../scripts/route-failures.ts | 333 ++ .../scripts/run-deterministic.ts | 367 ++ .../scripts/run-evaluate.ts | 922 ++++ .../mutagent-evaluator/scripts/run-judge.ts | 155 + .../scripts/run-pipeline.ts | 210 + .../mutagent-evaluator/scripts/run-review.ts | 266 ++ .../scripts/sample-traces.ts | 210 + .../mutagent-evaluator/scripts/self-audit.ts | 387 ++ .../mutagent-evaluator/scripts/source-map.ts | 106 + .../scripts/subject-profile.ts | 216 + .../mutagent-evaluator/scripts/substrate.ts | 170 + .../scripts/sync-eval-criteria.ts | 365 ++ .../mutagent-evaluator/scripts/ui-slots.ts | 119 + .../scripts/unitf-to-evaltrace.ts | 327 ++ .../scripts/validate-judge.ts | 358 ++ .../scripts/variance-compare.ts | 177 + .../scripts/verify-render.ts | 728 ++++ .../mutagent-diagnostics/behavior-tree.yaml | 140 + .../mutagent-diagnostics/eval-matrix.yaml | 1270 ++++++ .../methodology-review.yaml | 105 + .../workflows/audit.workflow.js | 82 + .../workflows/data-leak.workflow.js | 236 ++ .../workflows/variance.workflow.js | 163 + .../.agents/skills/mutagent-helix/SKILL.md | 113 + .../skills/mutagent-helix/orchestrator.md | 838 ++++ .../mutagent-helix/references/MONITORING.md | 209 + .../references/config-fields.md | 133 + .../references/config-migration.md | 168 + .../references/index-registry.md | 92 + .../skills/mutagent-helix/routing.yaml | 478 +++ .../scripts/cli/codex-transcode.ts | 143 + .../mutagent-helix/scripts/cli/doctor.ts | 111 + .../skills/mutagent-helix/scripts/cli/init.ts | 561 +++ .../skills/mutagent-helix/scripts/cli/run.sh | 73 + .../scripts/cli/skill-runtime-deps.ts | 502 +++ .../mutagent-helix/scripts/config-schema.ts | 1292 ++++++ .../skills/mutagent-helix/scripts/dispatch.ts | 503 +++ .../scripts/dogfood/extract-feedback.ts | 203 + .../scripts/dogfood/reconstruct-trajectory.ts | 327 ++ .../scripts/dogfood/render-dogfood-report.ts | 347 ++ .../scripts/dogfood/resolve-subagents.ts | 160 + .../scripts/dogfood/run-report.ts | 265 ++ .../scripts/dogfood/slack-thread.ts | 106 + .../mutagent-helix/scripts/dogfood/types.ts | 257 ++ .../mutagent-helix/scripts/eval-routing.ts | 754 ++++ .../mutagent-helix/scripts/feedback-send.ts | 367 ++ .../skills/mutagent-helix/scripts/feedback.ts | 127 + .../skills/mutagent-helix/scripts/gate.ts | 255 ++ .../scripts/handover-contract.ts | 400 ++ .../scripts/index/build-index.ts | 418 ++ .../scripts/index/render-index.ts | 110 + .../mutagent-helix/scripts/lib/entrypoint.ts | 41 + .../scripts/monitor/daemon-control.ts | 104 + .../scripts/monitor/event-bus.ts | 113 + .../scripts/monitor/relay-cli.ts | 81 + .../scripts/monitor/session-store.ts | 287 ++ .../scripts/monitor/slack-listen.ts | 266 ++ .../scripts/monitor/slack-notify.ts | 111 + .../scripts/monitor/triggers.ts | 166 + .../scripts/onboarding-check.ts | 369 ++ .../mutagent-helix/scripts/render-roster.ts | 320 ++ .../scripts/resolve-credential.ts | 185 + .../mutagent-helix/scripts/resolve-paths.ts | 246 ++ .../mutagent-helix/scripts/slack/format.ts | 63 + .../mutagent-helix/scripts/slack/post.ts | 115 + .../mutagent-helix/scripts/slack/relay.ts | 119 + .../mutagent-helix/scripts/sync-index.ts | 311 ++ .../.agents/skills/mutagent-optimize/SKILL.md | 302 ++ .../scripts/contracts/amend-request.ts | 503 +++ .../scripts/lib/entrypoint.ts | 41 + .../scripts/loop-state-cli.ts | 421 ++ .../mutagent-optimize/scripts/loop-state.ts | 501 +++ .../scripts/optimize-loop-run.ts | 304 ++ .../.agents/skills/mutagent-ship/SKILL.md | 225 + .../assets/agents/ship-monitor.md | 311 ++ .../skills/mutagent-ship/scripts/changelog.ts | 212 + .../skills/mutagent-ship/scripts/ci-fsm.ts | 340 ++ .../mutagent-ship/scripts/diagnose-handoff.ts | 141 + .../mutagent-ship/scripts/refinement.ts | 333 ++ .../skills/mutagent-ship/scripts/rollback.ts | 207 + .../mutagent-ship/scripts/ship-manifest.ts | 375 ++ .../mutagent-ship/scripts/ship-report.ts | 265 ++ .../mutagent-ship/scripts/ship-status.ts | 154 + .../skills/mutagent-ship/scripts/watch.ts | 366 ++ .../.claude/agents/ai-architect.md | 383 ++ .../.claude/agents/ai-engineer.md | 373 ++ .../.claude/agents/audit-executor.md | 169 + .../.claude/agents/dataset-builder.md | 161 + .../.claude/agents/diagnostics-analyzer.md | 636 +++ .../.claude/agents/discovery.md | 445 ++ .../.claude/agents/dogfood-monitor.md | 266 ++ .../.claude/agents/evaluator.md | 1192 ++++++ .../localhost-3000/.claude/agents/monitor.md | 299 ++ .../.claude/agents/ship-monitor.md | 311 ++ .../skills/mutagent-agentspec/CLAUDE.md | 33 + .../skills/mutagent-agentspec/SKILL.md | 138 + .../agentspec.decisions.md | 33 + .../agent-support-triage/agentspec.yaml | 187 + .../agentspec.yaml | 185 + .../skill-release-brief/agentspec.yaml | 114 + .../workflow-incident-routing/agentspec.yaml | 117 + .../assets/templates/agentspec.yaml.tpl | 93 + .../skills/mutagent-agentspec/package.json | 11 + .../references/agentspec-0.3-field-catalog.md | 136 + .../references/frameworks/doc-pins.md | 53 + .../references/principles.md | 96 + .../references/requirements.yaml | 305 ++ .../workflows/orchestrator-protocol.md | 396 ++ .../mutagent-agentspec/scripts/cli/doctor.ts | 116 + .../mutagent-agentspec/scripts/cli/init.ts | 230 + .../mutagent-agentspec/scripts/cli/run.sh | 72 + .../scripts/config/resolve-spec-dir.ts | 199 + .../scripts/contract/agentspec.schema.ts | 830 ++++ .../scripts/lib/entrypoint.ts | 41 + .../scripts/setup/detect.ts | 67 + .../scripts/template/slot-checklist.ts | 175 + .../scripts/validate/semantic-validator.ts | 452 ++ .../scripts/validate/validate-spec.ts | 127 + .../.claude/skills/mutagent-builder/SKILL.md | 100 + .../assets/agents/ai-architect.md | 383 ++ .../assets/agents/ai-engineer.md | 373 ++ .../assets/fixtures/plan-only/build-report.md | 54 + .../assets/templates/build-report.md.tpl | 79 + .../skills/mutagent-builder/package.json | 10 + .../mutagent-builder/references/principles.md | 18 + .../references/workflows/build-protocol.md | 121 + .../references/workflows/optimize-handoff.md | 23 + .../mutagent-builder/scripts/cli/run.sh | 72 + .../scripts/handoff/validate-build-input.ts | 76 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/sync-spec/check-sync-spec.ts | 524 +++ .../scripts/verify/spec-impl-coverage.ts | 185 + .../skills/mutagent-diagnostics/README.md | 192 + .../skills/mutagent-diagnostics/SKILL.md | 362 ++ .../assets/agents/diagnostics-analyzer.md | 636 +++ .../assets/templates/audit.json.tpl | 24 + .../assets/templates/audit.md.tpl | 49 + .../assets/templates/config.yaml.tpl | 100 + .../assets/templates/pr-body.md.tpl | 56 + .../assets/templates/report.html.tpl | 390 ++ .../assets/templates/shared/README.md | 27 + .../templates/shared/iter-N-handover.md.tpl | 125 + .../self-diagnosis-contract.v0.1.0.yaml.tpl | 234 + .../assets/templates/shared/spec.yaml.tpl | 152 + .../assets/templates/shared/team.yaml.tpl | 127 + .../shared/wave-N-dashboard.html.tpl | 1712 ++++++++ .../wireframes/diagnostics/WF-2.1-nl-query.md | 59 + .../diagnostics/WF-2.2-tier0-progress.md | 58 + .../diagnostics/WF-2.3-analysis-progress.md | 44 + .../diagnostics/WF-2.4-html-report.md | 61 + .../diagnostics/WF-2.5-rca-detail.md | 69 + .../diagnostics/WF-2.6-stale-warning.md | 53 + .../wireframes/onboarding/WF-1.1-welcome.md | 60 + .../WF-1.2-source-platform-picker.md | 41 + .../onboarding/WF-1.3-source-auth.md | 75 + .../onboarding/WF-1.4-target-picker.md | 48 + .../wireframes/onboarding/WF-1.5-ask-tool.md | 43 + .../onboarding/WF-1.6-config-review.md | 57 + .../onboarding/WF-1.7-filter-defaults.md | 52 + .../wireframes/onboarding/WF-1.8-first-run.md | 59 + .../examples/sample-findings.json | 92 + .../examples/sample-meta.json | 47 + .../skills/mutagent-diagnostics/package.json | 14 + .../references/adapter-strategy.md | 75 + .../references/config-migration.md | 93 + .../mutagent-diagnostics/references/config.md | 159 + .../references/filter-search-matrix.md | 66 + .../references/harness-knowledge.md | 22 + .../references/memory-format.md | 78 + .../references/onboarding-decisions.yaml | 187 + .../references/operation-inventory.md | 59 + .../references/overview.md | 167 + .../references/reference.md | 124 + .../references/script-index.md | 101 + .../references/source-adapter-contract.md | 93 + .../claude-code-transcripts.md | 66 + .../source-platforms/codex-transcripts.md | 78 + .../references/source-platforms/codex.md | 145 + .../source-platforms/install-paths.md | 57 + .../references/source-platforms/langfuse.md | 178 + .../source-platforms/local-jsonl.md | 55 + .../source-platforms/openobserve.md | 102 + .../references/source-platforms/otel.md | 63 + .../references/target-platforms/cloud-rest.md | 84 + .../target-platforms/local-claude.md | 65 + .../target-platforms/local-cloud-agent-sdk.md | 92 + .../target-platforms/local-codex.md | 72 + .../target-platforms/local-cursor.md | 108 + .../target-platforms/local-mastra.md | 77 + .../target-platforms/local-opencode.md | 70 + .../workflows/apply-pr-comment-format.md | 82 + .../references/workflows/diagnostics.md | 35 + .../references/workflows/handover-contract.md | 247 ++ .../references/workflows/onboarding.md | 314 ++ .../workflows/orchestrator-protocol.md | 1933 +++++++++ .../references/workflows/rca.md | 331 ++ .../references/workflows/rendering-anatomy.md | 314 ++ .../references/workflows/schedule-prep.md | 100 + .../references/workflows/scope-model.md | 128 + .../workflows/verification-methodology.md | 174 + .../scripts/aggregate/sort-findings.ts | Bin 0 -> 5084 bytes .../scripts/awareness/blind-spots.ts | 168 + .../scripts/awareness/llm-sample.ts | 682 +++ .../scripts/cli/doctor.ts | 369 ++ .../mutagent-diagnostics/scripts/cli/init.ts | 1057 +++++ .../scripts/cli/install-agents.ts | 374 ++ .../mutagent-diagnostics/scripts/cli/run.sh | 73 + .../scripts/cli/runtime-deps.ts | 296 ++ .../scripts/cli/shared-templates.ts | 79 + .../scripts/config/load.ts | 400 ++ .../scripts/config/resolve-credential.ts | 120 + .../scripts/config/schema.ts | 692 +++ .../scripts/config/validate.ts | 140 + .../scripts/config/write.ts | 166 + .../context/build-diagnosis-context.ts | 418 ++ .../scripts/context/load-context.ts | 106 + .../scripts/contract/types.ts | 166 + .../scripts/enrich/build-render-input.ts | 2081 +++++++++ .../scripts/enrich/corpus-severity.ts | 172 + .../scripts/enrich/dismissal-match.ts | 270 ++ .../scripts/enrich/rank-remedies.ts | 176 + .../scripts/hooks/install-hooks.sh | 46 + .../scripts/hooks/pre-push.sh | 78 + .../scripts/invocation/parse-brief.ts | 190 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/library/match.ts | 114 + .../scripts/library/paths.ts | 95 + .../scripts/library/store.ts | 536 +++ .../scripts/library/types.ts | 181 + .../scripts/lint/template-inline-js.ts | 268 ++ .../scripts/memory/append.ts | 189 + .../scripts/memory/read.ts | 219 + .../normalize/platforms/entity-context.ts | 686 +++ .../scripts/normalize/read-unitf.ts | 668 +++ .../scripts/normalize/trace.ts | 1195 ++++++ .../scripts/normalize/unitf-adapter.ts | Bin 0 -> 16563 bytes .../scripts/normalize/unitf-types.ts | 213 + .../scripts/report/persist-selections.ts | 175 + .../scripts/report/render.ts | 3534 ++++++++++++++++ .../scripts/run/diagnose.ts | 65 + .../scripts/run/session.ts | 168 + .../scripts/sample/caps.ts | 347 ++ .../scripts/sample/deep-read-gate.ts | 461 ++ .../scripts/sample/representative.ts | 585 +++ .../scripts/scan/objection.ts | 224 + .../scripts/scan/trajectory.ts | 492 +++ .../scripts/self-diagnostics/dispatch.ts | 136 + .../scripts/self-diagnostics/probe.ts | 171 + .../scripts/setup/detect.ts | 345 ++ .../scripts/setup/ensure-cli.ts | 315 ++ .../scripts/setup/reconfigure.ts | 78 + .../scripts/setup/verify-agents.ts | 208 + .../mutagent-diagnostics/scripts/slicer.ts | 167 + .../scripts/source/adapters/claude-code.ts | 17 + .../scripts/source/adapters/codex.ts | 11 + .../scripts/source/adapters/langfuse.ts | 17 + .../scripts/source/adapters/local-jsonl.ts | 12 + .../scripts/source/adapters/otel.ts | 12 + .../scripts/source/index.ts | 54 + .../scripts/source/registry.ts | 45 + .../scripts/source/types.ts | 86 + .../scripts/stale-detector.ts | 75 + .../scripts/test/render-playwright.cli.ts | 477 +++ .../scripts/tier0-scan.ts | 431 ++ .../scripts/tier0/claude-code.ts | 139 + .../scripts/tier0/langfuse.ts | 149 + .../scripts/validate/completeness-check.ts | 437 ++ .../scripts/validate/doc-refs.ts | 191 + .../scripts/validate/finalize-gate.ts | 418 ++ .../scripts/validate/findings-contract.ts | 643 +++ .../scripts/validate/render-js-syntax.ts | 190 + .../scripts/validate/report-checklist.yaml | 217 + .../scripts/validate/trace-shape.ts | 263 ++ .../scripts/validate/wave6-checklist.ts | 327 ++ .../skills/mutagent-evaluator/SKILL.md | 548 +++ .../assets/agents/audit-executor.md | 169 + .../assets/agents/dataset-builder.md | 161 + .../assets/agents/evaluator.md | 1192 ++++++ .../mutagent-evaluator/assets/brand/theme.css | 213 + .../assets/brand/wordmark.html | 9 + .../assets/code-quality-criteria.yaml | 75 + .../templates/discover-report.template.html | 397 ++ .../templates/eval-report.template.html | 594 +++ .../templates/review-report.template.html | 560 +++ .../golden/judge-trajectory.prose.md | 90 + .../lenses/context-flow-lens.md | 85 + .../mutagent-evaluator/lenses/data-lens.md | 47 + .../lenses/decision-lens.md | 48 + .../lenses/methodology-critic-lens.md | 53 + .../lenses/trajectory-lens.md | 44 + .../skills/mutagent-evaluator/package.json | 14 + .../references/build-review-interface.md | 83 + .../references/data-registry.md | 43 + .../mutagent-evaluator/references/edd-loop.md | 134 + .../references/error-analysis.md | 113 + .../references/eval-audit.md | 154 + .../references/eval-layers.md | 106 + .../references/eval-stage.md | 201 + .../references/generate-synthetic-data.md | 81 + .../references/grounded-adjudication.md | 221 + .../references/handoff-format.md | 89 + .../references/memory-format.md | 65 + .../references/methodology.md | 201 + .../references/operation-inventory.md | 197 + .../references/validate-evaluator.md | 125 + .../workflows/orchestrator-protocol.md | 319 ++ .../references/write-judge-prompt.md | 123 + .../schemas/behavior-tree.schema.yaml | 73 + .../schemas/dataset.schema.yaml | 66 + .../schemas/edd-change-request.schema.yaml | 114 + .../schemas/eval-matrix.schema.yaml | 74 + .../schemas/flow-graph.schema.yaml | 69 + .../schemas/flow-profile.schema.yaml | 49 + .../schemas/methodology-review.schema.yaml | 40 + .../schemas/scorecard.schema.yaml | 112 + .../scripts/agent-dispatch.ts | Bin 0 -> 10781 bytes .../scripts/aggregate-discover.ts | 881 ++++ .../scripts/apply-rulings.ts | 245 ++ .../scripts/artifact-paths.ts | 115 + .../scripts/assemble-scorecard.ts | 172 + .../mutagent-evaluator/scripts/audience.ts | 84 + .../scripts/build-dataset.ts | 186 + .../mutagent-evaluator/scripts/build-evals.ts | 93 + .../scripts/build-review-ui.ts | 707 ++++ .../scripts/check-method-router.ts | 170 + .../scripts/cli/aggregate.ts | 112 + .../scripts/cli/audit-run.ts | 182 + .../mutagent-evaluator/scripts/cli/doctor.ts | 212 + .../mutagent-evaluator/scripts/cli/dogfood.ts | 133 + .../mutagent-evaluator/scripts/cli/init.ts | 646 +++ .../scripts/cli/methodology-review.ts | 122 + .../mutagent-evaluator/scripts/cli/prep.ts | 325 ++ .../scripts/cli/profile-subject.ts | 165 + .../mutagent-evaluator/scripts/cli/run.sh | 68 + .../scripts/cli/runtime-deps.ts | 298 ++ .../scripts/cli/variance-check.ts | 105 + .../scripts/code-eval-library.ts | 285 ++ .../mutagent-evaluator/scripts/code-eval.ts | 248 ++ .../scripts/code-quality-verdict.ts | 277 ++ .../scripts/codegen-evals.ts | 173 + .../scripts/cold-start-project.ts | 151 + .../scripts/cold-start-sampler.ts | 267 ++ .../mutagent-evaluator/scripts/config/load.ts | 343 ++ .../scripts/config/schema.ts | 380 ++ .../scripts/contracts/agentspec-evals.ts | 147 + .../scripts/contracts/dataset.ts | 149 + .../scripts/contracts/eval-engine.ts | 118 + .../scripts/contracts/eval-matrix.ts | 916 ++++ .../scripts/contracts/eval-types.ts | 1125 +++++ .../scripts/contracts/flow-graph.ts | 194 + .../scripts/contracts/types.ts | 303 ++ .../scripts/contracts/validation.ts | 193 + .../scripts/criterion-identity.ts | 267 ++ .../scripts/decisions-store.ts | 265 ++ .../scripts/derive-dataset.ts | 152 + .../scripts/determine-outcome.ts | 227 + .../scripts/diff-discriminate.ts | 160 + .../scripts/discover-criteria.ts | 348 ++ .../scripts/edd/change-request.ts | 232 + .../scripts/edd/edd-types.ts | 210 + .../scripts/edd/variance-gate.ts | 186 + .../scripts/emit-completeness.ts | 111 + .../mutagent-evaluator/scripts/eval-engine.ts | 160 + .../mutagent-evaluator/scripts/evaluate.ts | 333 ++ .../mutagent-evaluator/scripts/flow-graph.ts | 230 + .../scripts/judge-prompt-template.ts | 382 ++ .../scripts/judge-provider.ts | 135 + .../scripts/lib/entrypoint.ts | 41 + .../scripts/lint-grounding.ts | 229 + .../scripts/lint-uniformity.ts | 168 + .../scripts/living-suite.ts | 109 + .../mutagent-evaluator/scripts/load-bundle.ts | 203 + .../scripts/load-profile-vocab.ts | 64 + .../scripts/load-profile.ts | 106 + .../skills/mutagent-evaluator/scripts/mask.ts | 139 + .../scripts/materialize-dataset.ts | 175 + .../scripts/matrix-judge.ts | 1070 +++++ .../scripts/memory/append.ts | 215 + .../scripts/memory/ratify.ts | 165 + .../mutagent-evaluator/scripts/memory/read.ts | 168 + .../scripts/merge-criteria.ts | 887 ++++ .../scripts/persist-eval-criteria.ts | 232 + .../mutagent-evaluator/scripts/prep-tasks.ts | 136 + .../scripts/profile-subject.ts | 310 ++ .../scripts/publish-report.ts | 132 + .../scripts/read-manifest.ts | 120 + .../scripts/read-unitf-traces.ts | 113 + .../scripts/render-build-cards.ts | 232 + .../scripts/render-discover-report-v3.ts | 1242 ++++++ .../scripts/render-discover-report.ts | 1640 +++++++ .../scripts/render-eval-report-v3.ts | 743 ++++ .../scripts/render-eval-report.ts | 3757 +++++++++++++++++ .../scripts/render-report.ts | 212 + .../scripts/render-review-report-v3.ts | 720 ++++ .../scripts/report-fragments.ts | 173 + .../scripts/resolve-credential.ts | 110 + .../mutagent-evaluator/scripts/resolve-ref.ts | 98 + .../scripts/result-verify.ts | 129 + .../scripts/route-failures.ts | 333 ++ .../scripts/run-deterministic.ts | 367 ++ .../scripts/run-evaluate.ts | 922 ++++ .../mutagent-evaluator/scripts/run-judge.ts | 155 + .../scripts/run-pipeline.ts | 210 + .../mutagent-evaluator/scripts/run-review.ts | 266 ++ .../scripts/sample-traces.ts | 210 + .../mutagent-evaluator/scripts/self-audit.ts | 387 ++ .../mutagent-evaluator/scripts/source-map.ts | 106 + .../scripts/subject-profile.ts | 216 + .../mutagent-evaluator/scripts/substrate.ts | 170 + .../scripts/sync-eval-criteria.ts | 365 ++ .../mutagent-evaluator/scripts/ui-slots.ts | 119 + .../scripts/unitf-to-evaltrace.ts | 327 ++ .../scripts/validate-judge.ts | 358 ++ .../scripts/variance-compare.ts | 177 + .../scripts/verify-render.ts | 728 ++++ .../mutagent-diagnostics/behavior-tree.yaml | 140 + .../mutagent-diagnostics/eval-matrix.yaml | 1270 ++++++ .../methodology-review.yaml | 105 + .../workflows/audit.workflow.js | 82 + .../workflows/data-leak.workflow.js | 236 ++ .../workflows/variance.workflow.js | 163 + .../.claude/skills/mutagent-helix/SKILL.md | 113 + .../skills/mutagent-helix/orchestrator.md | 838 ++++ .../mutagent-helix/references/MONITORING.md | 209 + .../references/config-fields.md | 133 + .../references/config-migration.md | 168 + .../references/index-registry.md | 92 + .../skills/mutagent-helix/routing.yaml | 478 +++ .../scripts/cli/codex-transcode.ts | 143 + .../mutagent-helix/scripts/cli/doctor.ts | 111 + .../skills/mutagent-helix/scripts/cli/init.ts | 561 +++ .../skills/mutagent-helix/scripts/cli/run.sh | 73 + .../scripts/cli/skill-runtime-deps.ts | 502 +++ .../mutagent-helix/scripts/config-schema.ts | 1292 ++++++ .../skills/mutagent-helix/scripts/dispatch.ts | 503 +++ .../scripts/dogfood/extract-feedback.ts | 203 + .../scripts/dogfood/reconstruct-trajectory.ts | 327 ++ .../scripts/dogfood/render-dogfood-report.ts | 347 ++ .../scripts/dogfood/resolve-subagents.ts | 160 + .../scripts/dogfood/run-report.ts | 265 ++ .../scripts/dogfood/slack-thread.ts | 106 + .../mutagent-helix/scripts/dogfood/types.ts | 257 ++ .../mutagent-helix/scripts/eval-routing.ts | 754 ++++ .../mutagent-helix/scripts/feedback-send.ts | 367 ++ .../skills/mutagent-helix/scripts/feedback.ts | 127 + .../skills/mutagent-helix/scripts/gate.ts | 255 ++ .../scripts/handover-contract.ts | 400 ++ .../scripts/index/build-index.ts | 418 ++ .../scripts/index/render-index.ts | 110 + .../mutagent-helix/scripts/lib/entrypoint.ts | 41 + .../scripts/monitor/daemon-control.ts | 104 + .../scripts/monitor/event-bus.ts | 113 + .../scripts/monitor/relay-cli.ts | 81 + .../scripts/monitor/session-store.ts | 287 ++ .../scripts/monitor/slack-listen.ts | 266 ++ .../scripts/monitor/slack-notify.ts | 111 + .../scripts/monitor/triggers.ts | 166 + .../scripts/onboarding-check.ts | 369 ++ .../mutagent-helix/scripts/render-roster.ts | 320 ++ .../scripts/resolve-credential.ts | 185 + .../mutagent-helix/scripts/resolve-paths.ts | 246 ++ .../mutagent-helix/scripts/slack/format.ts | 63 + .../mutagent-helix/scripts/slack/post.ts | 115 + .../mutagent-helix/scripts/slack/relay.ts | 119 + .../mutagent-helix/scripts/sync-index.ts | 311 ++ .../.claude/skills/mutagent-optimize/SKILL.md | 302 ++ .../scripts/contracts/amend-request.ts | 503 +++ .../scripts/lib/entrypoint.ts | 41 + .../scripts/loop-state-cli.ts | 421 ++ .../mutagent-optimize/scripts/loop-state.ts | 501 +++ .../scripts/optimize-loop-run.ts | 304 ++ .../.claude/skills/mutagent-ship/SKILL.md | 225 + .../assets/agents/ship-monitor.md | 311 ++ .../.claude/skills/mutagent-ship/package.json | 10 + .../skills/mutagent-ship/scripts/changelog.ts | 212 + .../skills/mutagent-ship/scripts/ci-fsm.ts | 340 ++ .../mutagent-ship/scripts/diagnose-handoff.ts | 141 + .../mutagent-ship/scripts/refinement.ts | 333 ++ .../skills/mutagent-ship/scripts/rollback.ts | 207 + .../mutagent-ship/scripts/ship-manifest.ts | 375 ++ .../mutagent-ship/scripts/ship-report.ts | 265 ++ .../mutagent-ship/scripts/ship-status.ts | 154 + .../skills/mutagent-ship/scripts/watch.ts | 366 ++ .../.codex/agents/ai-architect.toml | 377 ++ .../.codex/agents/ai-engineer.toml | 368 ++ .../.codex/agents/audit-executor.toml | 165 + .../.codex/agents/dataset-builder.toml | 157 + .../.codex/agents/diagnostics-analyzer.toml | 636 +++ .../.codex/agents/discovery.toml | 443 ++ .../.codex/agents/dogfood-monitor.toml | 262 ++ .../.codex/agents/evaluator.toml | 1188 ++++++ .../localhost-3000/.codex/agents/monitor.toml | 295 ++ .../.codex/agents/ship-monitor.toml | 305 ++ .../localhost-3000/.mutagent/config.yaml | 23 + .../agentspec.decisions.md | 31 + .../agentspec.yaml | 388 ++ submissions/localhost-3000/.mutagentrc.json | 5 + submissions/localhost-3000/.vercel/README.txt | 11 + .../localhost-3000/.vercel/project.json | 1 + .../localhost-3000/.vscode/settings.json | 3 + submissions/localhost-3000/AGENTS.md | 16 + submissions/localhost-3000/CLAUDE.md | 9 + ...bix-first-pass-candidate-evaluator.eval.ts | 287 ++ .../orbix-first-pass-candidate-evaluator.ts | 380 ++ .../localhost-3000/ai-interview-agent.html | 34 + .../localhost-3000/ai-verification.html | 41 + submissions/localhost-3000/analytics.html | 39 + submissions/localhost-3000/app.js | 2173 ++++++++++ submissions/localhost-3000/call-summary.html | 34 + .../localhost-3000/candidate-detail.html | 34 + .../localhost-3000/candidate-report.html | 121 + submissions/localhost-3000/candidates.html | 430 ++ submissions/localhost-3000/dashboard.html | 132 + submissions/localhost-3000/dev-dashboard.html | 38 + submissions/localhost-3000/dev-dashboard.js | 128 + submissions/localhost-3000/login.html | 187 + submissions/localhost-3000/qrchandu.png | Bin 0 -> 9812 bytes submissions/localhost-3000/qrcode.png | Bin 0 -> 3556 bytes submissions/localhost-3000/qrgane.png | Bin 0 -> 9373 bytes submissions/localhost-3000/qrsowm.png | Bin 0 -> 9815 bytes .../localhost-3000/resume-analysis.html | 41 + .../localhost-3000/skill-passport.html | 34 + submissions/localhost-3000/styles.css | 403 ++ 823 files changed, 215979 insertions(+) create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/CLAUDE.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.decisions.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/multiagent-controlled-release/agentspec.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/skill-release-brief/agentspec.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/workflow-incident-routing/agentspec.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/agentspec-0.3-field-catalog.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/frameworks/doc-pins.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/principles.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/requirements.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/setup/detect.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/template/slot-checklist.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/semantic-validator.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/validate-spec.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-architect.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-engineer.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/assets/fixtures/plan-only/build-report.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/assets/templates/build-report.md.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/references/principles.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/build-protocol.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/optimize-handoff.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/handoff/validate-build-input.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/README.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/audit.json.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/audit.md.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/report.html.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/README.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-findings.json create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-meta.json create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/adapter-strategy.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config-migration.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/filter-search-matrix.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/harness-knowledge.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/memory-format.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/onboarding-decisions.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/operation-inventory.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/overview.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/reference.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/script-index.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-adapter-contract.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/codex.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/install-paths.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/langfuse.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/openobserve.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/source-platforms/otel.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-claude.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-codex.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/diagnostics.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/handover-contract.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/onboarding.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/rca.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/schedule-prep.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/scope-model.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/workflows/verification-methodology.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/install-agents.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/runtime-deps.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/config/load.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/config/schema.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/config/validate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/config/write.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/context/load-context.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/contract/types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/library/match.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/library/paths.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/library/store.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/library/types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/memory/append.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/memory/read.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/normalize/trace.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/report/persist-selections.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/report/render.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/run/diagnose.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/run/session.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/sample/caps.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/sample/representative.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/scan/objection.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/scan/trajectory.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/setup/detect.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/slicer.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/index.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/registry.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/source/types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/stale-detector.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/tier0-scan.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/agents/audit-executor.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/agents/dataset-builder.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/agents/evaluator.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/brand/theme.css create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/brand/wordmark.html create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/code-quality-criteria.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/templates/discover-report.template.html create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/templates/eval-report.template.html create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/assets/templates/review-report.template.html create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/golden/judge-trajectory.prose.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/lenses/context-flow-lens.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/lenses/data-lens.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/lenses/decision-lens.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/lenses/methodology-critic-lens.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/lenses/trajectory-lens.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/build-review-interface.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/data-registry.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/edd-loop.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/error-analysis.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/eval-audit.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/eval-layers.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/eval-stage.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/generate-synthetic-data.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/grounded-adjudication.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/handoff-format.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/memory-format.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/methodology.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/operation-inventory.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/validate-evaluator.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/references/write-judge-prompt.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/dataset.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/schemas/scorecard.schema.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/agent-dispatch.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/aggregate-discover.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/apply-rulings.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/artifact-paths.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/assemble-scorecard.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/audience.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/build-dataset.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/build-evals.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/build-review-ui.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/check-method-router.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/aggregate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/audit-run.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/dogfood.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/methodology-review.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/prep.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/profile-subject.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/runtime-deps.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cli/variance-check.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/code-eval-library.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/code-eval.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/code-quality-verdict.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/codegen-evals.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cold-start-project.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/cold-start-sampler.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/config/load.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/config/schema.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/dataset.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/eval-types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/contracts/validation.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/criterion-identity.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/decisions-store.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/derive-dataset.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/determine-outcome.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/diff-discriminate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/discover-criteria.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/edd/change-request.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/edd/edd-types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/edd/variance-gate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/emit-completeness.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/eval-engine.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/evaluate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/flow-graph.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/judge-prompt-template.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/judge-provider.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/lint-grounding.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/lint-uniformity.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/living-suite.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/load-bundle.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/load-profile-vocab.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/load-profile.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/mask.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/materialize-dataset.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/matrix-judge.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/memory/append.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/memory/ratify.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/memory/read.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/merge-criteria.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/prep-tasks.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/profile-subject.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/publish-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/read-manifest.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/read-unitf-traces.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-build-cards.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-discover-report-v3.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-discover-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-eval-report-v3.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-eval-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/render-review-report-v3.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/report-fragments.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/resolve-credential.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/resolve-ref.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/result-verify.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/route-failures.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/run-deterministic.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/run-evaluate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/run-judge.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/run-pipeline.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/run-review.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/sample-traces.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/self-audit.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/source-map.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/subject-profile.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/substrate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/ui-slots.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/validate-judge.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/variance-compare.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/scripts/verify-render.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/workflows/audit.workflow.js create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/workflows/data-leak.workflow.js create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-evaluator/workflows/variance.workflow.js create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/orchestrator.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/references/MONITORING.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/references/config-fields.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/references/config-migration.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/references/index-registry.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/routing.yaml create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/cli/codex-transcode.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/cli/skill-runtime-deps.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/config-schema.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dispatch.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/extract-feedback.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/reconstruct-trajectory.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/render-dogfood-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/resolve-subagents.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/run-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/slack-thread.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/dogfood/types.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/eval-routing.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/feedback-send.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/feedback.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/gate.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/handover-contract.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/index/build-index.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/index/render-index.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/daemon-control.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/event-bus.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/relay-cli.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/session-store.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/slack-listen.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/slack-notify.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/monitor/triggers.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/onboarding-check.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/render-roster.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/resolve-credential.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/resolve-paths.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/slack/format.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/slack/post.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/slack/relay.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-helix/scripts/sync-index.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/scripts/contracts/amend-request.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/scripts/loop-state-cli.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/scripts/loop-state.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-optimize/scripts/optimize-loop-run.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/SKILL.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/assets/agents/ship-monitor.md create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/changelog.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/ci-fsm.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/diagnose-handoff.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/refinement.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/rollback.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/ship-manifest.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/ship-report.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/ship-status.ts create mode 100644 submissions/localhost-3000/.agents/skills/mutagent-ship/scripts/watch.ts create mode 100644 submissions/localhost-3000/.claude/agents/ai-architect.md create mode 100644 submissions/localhost-3000/.claude/agents/ai-engineer.md create mode 100644 submissions/localhost-3000/.claude/agents/audit-executor.md create mode 100644 submissions/localhost-3000/.claude/agents/dataset-builder.md create mode 100644 submissions/localhost-3000/.claude/agents/diagnostics-analyzer.md create mode 100644 submissions/localhost-3000/.claude/agents/discovery.md create mode 100644 submissions/localhost-3000/.claude/agents/dogfood-monitor.md create mode 100644 submissions/localhost-3000/.claude/agents/evaluator.md create mode 100644 submissions/localhost-3000/.claude/agents/monitor.md create mode 100644 submissions/localhost-3000/.claude/agents/ship-monitor.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/CLAUDE.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.decisions.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/examples/multiagent-controlled-release/agentspec.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/examples/skill-release-brief/agentspec.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/examples/workflow-incident-routing/agentspec.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/package.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/references/agentspec-0.3-field-catalog.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/references/frameworks/doc-pins.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/references/principles.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/references/requirements.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/setup/detect.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/template/slot-checklist.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/validate/semantic-validator.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-agentspec/scripts/validate/validate-spec.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/assets/agents/ai-architect.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/assets/fixtures/plan-only/build-report.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/assets/templates/build-report.md.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/package.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/references/principles.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/references/workflows/build-protocol.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/references/workflows/optimize-handoff.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/scripts/handoff/validate-build-input.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/README.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/agents/diagnostics-analyzer.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/audit.json.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/audit.md.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/config.yaml.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/pr-body.md.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/report.html.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/README.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/examples/sample-findings.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/examples/sample-meta.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/package.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/adapter-strategy.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/config-migration.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/config.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/filter-search-matrix.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/harness-knowledge.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/memory-format.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/onboarding-decisions.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/operation-inventory.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/overview.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/reference.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/script-index.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-adapter-contract.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/claude-code-transcripts.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/codex-transcripts.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/codex.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/install-paths.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/langfuse.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/local-jsonl.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/openobserve.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/source-platforms/otel.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/cloud-rest.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-claude.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cloud-agent-sdk.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-codex.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-cursor.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-mastra.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/target-platforms/local-opencode.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/apply-pr-comment-format.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/diagnostics.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/handover-contract.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/onboarding.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/rca.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/rendering-anatomy.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/schedule-prep.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/scope-model.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/references/workflows/verification-methodology.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/aggregate/sort-findings.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/awareness/blind-spots.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/awareness/llm-sample.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/install-agents.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/runtime-deps.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/cli/shared-templates.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/config/load.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/config/resolve-credential.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/config/schema.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/config/validate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/config/write.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/context/build-diagnosis-context.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/context/load-context.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/contract/types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/enrich/build-render-input.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/enrich/corpus-severity.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/enrich/dismissal-match.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/enrich/rank-remedies.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/hooks/install-hooks.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/hooks/pre-push.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/invocation/parse-brief.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/library/match.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/library/paths.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/library/store.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/library/types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/lint/template-inline-js.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/memory/append.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/memory/read.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/normalize/platforms/entity-context.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/normalize/read-unitf.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/normalize/trace.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-adapter.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/normalize/unitf-types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/report/persist-selections.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/report/render.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/run/diagnose.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/run/session.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/sample/caps.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/sample/deep-read-gate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/sample/representative.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/scan/objection.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/scan/trajectory.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/dispatch.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/self-diagnostics/probe.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/setup/detect.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/setup/ensure-cli.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/setup/reconfigure.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/setup/verify-agents.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/slicer.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/adapters/claude-code.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/adapters/codex.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/adapters/langfuse.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/adapters/local-jsonl.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/adapters/otel.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/index.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/registry.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/source/types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/stale-detector.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/test/render-playwright.cli.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/tier0-scan.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/tier0/claude-code.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/tier0/langfuse.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/completeness-check.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/doc-refs.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/finalize-gate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/findings-contract.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/render-js-syntax.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/report-checklist.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/trace-shape.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-diagnostics/scripts/validate/wave6-checklist.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/agents/audit-executor.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/agents/dataset-builder.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/agents/evaluator.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/brand/theme.css create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/brand/wordmark.html create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/code-quality-criteria.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/templates/discover-report.template.html create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/templates/eval-report.template.html create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/assets/templates/review-report.template.html create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/golden/judge-trajectory.prose.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/lenses/context-flow-lens.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/lenses/data-lens.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/lenses/decision-lens.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/lenses/methodology-critic-lens.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/lenses/trajectory-lens.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/package.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/build-review-interface.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/data-registry.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/edd-loop.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/error-analysis.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/eval-audit.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/eval-layers.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/eval-stage.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/generate-synthetic-data.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/grounded-adjudication.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/handoff-format.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/memory-format.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/methodology.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/operation-inventory.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/validate-evaluator.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/workflows/orchestrator-protocol.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/references/write-judge-prompt.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/behavior-tree.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/dataset.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/edd-change-request.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/eval-matrix.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/flow-graph.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/flow-profile.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/methodology-review.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/schemas/scorecard.schema.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/agent-dispatch.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/aggregate-discover.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/apply-rulings.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/artifact-paths.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/assemble-scorecard.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/audience.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/build-dataset.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/build-evals.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/build-review-ui.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/check-method-router.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/aggregate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/audit-run.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/dogfood.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/methodology-review.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/prep.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/profile-subject.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/runtime-deps.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cli/variance-check.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/code-eval-library.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/code-eval.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/code-quality-verdict.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/codegen-evals.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cold-start-project.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/cold-start-sampler.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/config/load.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/config/schema.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/agentspec-evals.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/dataset.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/eval-engine.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/eval-matrix.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/eval-types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/flow-graph.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/contracts/validation.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/criterion-identity.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/decisions-store.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/derive-dataset.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/determine-outcome.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/diff-discriminate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/discover-criteria.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/edd/change-request.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/edd/edd-types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/edd/variance-gate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/emit-completeness.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/eval-engine.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/evaluate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/flow-graph.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/judge-prompt-template.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/judge-provider.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/lint-grounding.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/lint-uniformity.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/living-suite.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/load-bundle.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/load-profile-vocab.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/load-profile.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/mask.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/materialize-dataset.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/matrix-judge.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/memory/append.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/memory/ratify.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/memory/read.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/merge-criteria.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/persist-eval-criteria.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/prep-tasks.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/profile-subject.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/publish-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/read-manifest.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/read-unitf-traces.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-build-cards.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-discover-report-v3.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-discover-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-eval-report-v3.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-eval-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/render-review-report-v3.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/report-fragments.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/resolve-credential.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/resolve-ref.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/result-verify.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/route-failures.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/run-deterministic.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/run-evaluate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/run-judge.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/run-pipeline.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/run-review.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/sample-traces.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/self-audit.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/source-map.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/subject-profile.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/substrate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/ui-slots.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/unitf-to-evaltrace.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/validate-judge.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/variance-compare.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/scripts/verify-render.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/behavior-tree.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/eval-matrix.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/subjects/mutagent-diagnostics/methodology-review.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/workflows/audit.workflow.js create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/workflows/data-leak.workflow.js create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-evaluator/workflows/variance.workflow.js create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/orchestrator.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/references/MONITORING.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/references/config-fields.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/references/config-migration.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/references/index-registry.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/routing.yaml create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/cli/codex-transcode.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/cli/doctor.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/cli/init.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/cli/run.sh create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/cli/skill-runtime-deps.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/config-schema.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dispatch.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/extract-feedback.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/reconstruct-trajectory.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/render-dogfood-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/resolve-subagents.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/run-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/slack-thread.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/dogfood/types.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/eval-routing.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/feedback-send.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/feedback.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/gate.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/handover-contract.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/index/build-index.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/index/render-index.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/daemon-control.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/event-bus.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/relay-cli.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/session-store.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/slack-listen.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/slack-notify.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/monitor/triggers.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/onboarding-check.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/render-roster.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/resolve-credential.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/resolve-paths.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/slack/format.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/slack/post.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/slack/relay.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-helix/scripts/sync-index.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/scripts/contracts/amend-request.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/scripts/lib/entrypoint.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/scripts/loop-state-cli.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/scripts/loop-state.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-optimize/scripts/optimize-loop-run.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/SKILL.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/assets/agents/ship-monitor.md create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/package.json create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/changelog.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/ci-fsm.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/diagnose-handoff.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/refinement.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/rollback.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/ship-manifest.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/ship-report.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/ship-status.ts create mode 100644 submissions/localhost-3000/.claude/skills/mutagent-ship/scripts/watch.ts create mode 100644 submissions/localhost-3000/.codex/agents/ai-architect.toml create mode 100644 submissions/localhost-3000/.codex/agents/ai-engineer.toml create mode 100644 submissions/localhost-3000/.codex/agents/audit-executor.toml create mode 100644 submissions/localhost-3000/.codex/agents/dataset-builder.toml create mode 100644 submissions/localhost-3000/.codex/agents/diagnostics-analyzer.toml create mode 100644 submissions/localhost-3000/.codex/agents/discovery.toml create mode 100644 submissions/localhost-3000/.codex/agents/dogfood-monitor.toml create mode 100644 submissions/localhost-3000/.codex/agents/evaluator.toml create mode 100644 submissions/localhost-3000/.codex/agents/monitor.toml create mode 100644 submissions/localhost-3000/.codex/agents/ship-monitor.toml create mode 100644 submissions/localhost-3000/.mutagent/config.yaml create mode 100644 submissions/localhost-3000/.mutagent/specs/orbix-first-pass-candidate-evaluator/agentspec.decisions.md create mode 100644 submissions/localhost-3000/.mutagent/specs/orbix-first-pass-candidate-evaluator/agentspec.yaml create mode 100644 submissions/localhost-3000/.mutagentrc.json create mode 100644 submissions/localhost-3000/.vercel/README.txt create mode 100644 submissions/localhost-3000/.vercel/project.json create mode 100644 submissions/localhost-3000/.vscode/settings.json create mode 100644 submissions/localhost-3000/AGENTS.md create mode 100644 submissions/localhost-3000/CLAUDE.md create mode 100644 submissions/localhost-3000/agents/orbix-first-pass-candidate-evaluator.eval.ts create mode 100644 submissions/localhost-3000/agents/orbix-first-pass-candidate-evaluator.ts create mode 100644 submissions/localhost-3000/ai-interview-agent.html create mode 100644 submissions/localhost-3000/ai-verification.html create mode 100644 submissions/localhost-3000/analytics.html create mode 100644 submissions/localhost-3000/app.js create mode 100644 submissions/localhost-3000/call-summary.html create mode 100644 submissions/localhost-3000/candidate-detail.html create mode 100644 submissions/localhost-3000/candidate-report.html create mode 100644 submissions/localhost-3000/candidates.html create mode 100644 submissions/localhost-3000/dashboard.html create mode 100644 submissions/localhost-3000/dev-dashboard.html create mode 100644 submissions/localhost-3000/dev-dashboard.js create mode 100644 submissions/localhost-3000/login.html create mode 100644 submissions/localhost-3000/qrchandu.png create mode 100644 submissions/localhost-3000/qrcode.png create mode 100644 submissions/localhost-3000/qrgane.png create mode 100644 submissions/localhost-3000/qrsowm.png create mode 100644 submissions/localhost-3000/resume-analysis.html create mode 100644 submissions/localhost-3000/skill-passport.html create mode 100644 submissions/localhost-3000/styles.css diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/CLAUDE.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/CLAUDE.md new file mode 100644 index 00000000..52563adb --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/CLAUDE.md @@ -0,0 +1,33 @@ +# mutagent-agentspec — skill nav map (lean) + +> Lean per-skill navigation. The substantive surface is `SKILL.md`. This file points. + +`mutagent-agentspec` is the **ADL ① SPEC** stage: a guided requirements interview that emits a +portable, validated `agentspec.yaml`. The spec is the **Definition** (the interface — *what* the +agent IS); `mutagent-builder` later implements it via `*build`. The parent session IS the domain +orchestrator — it runs the interview itself and does **NOT** dispatch a coordinator sub-agent. + +## Where everything lives + +| You want… | Read | +|---|---| +| The skill surface (frontmatter · §0 setup · §0.1 star-commands · triggers · architecture) | `SKILL.md` | +| The `*spec` interview FSM (+ BUILD/EVALUATE handoffs) | `references/workflows/orchestrator-protocol.md` | +| Operative design principles (PR-NNN, operator-locked) | `references/principles.md` | +| Machine-readable requirements hub (REQ-NNN) | `references/requirements.yaml` | +| Pinned framework docs carried into BUILD | `references/frameworks/doc-pins.md` | +| The `agentspec.yaml` schema (TypeBox, versioned `agentspec.mutagent.io/v0.3.0`) | `scripts/contract/agentspec.schema.ts` | +| The SEMANTIC gate (kind leakage · graphs · member cycles · bounded loops · ref resolution) | `scripts/validate/semantic-validator.ts` | +| The schema gate (CLI: structural + semantic + FS decision-sidecar) | `scripts/validate/validate-spec.ts` | +| The normative 0.3.0 field catalog + implementation resolutions | `references/agentspec-0.3-field-catalog.md` | +| The worked, validated example spec (init scaffold) | `assets/templates/agentspec.yaml.tpl` | +| The four canonical commented examples (one per kind) | `assets/examples/{agent,skill,multiagent,workflow}-*/agentspec.yaml` | +| The valid/invalid fixture set | `assets/examples/` (valid) · `assets/fixtures/invalid/` (one violation each) | +| The four-kind interview-ordering fixtures | `assets/fixtures/interview/{agent,skill,multiagent,workflow}-interview.md` | +| The constitution pointer + in-repo PRD link | `.meta/design-principles.md` | + +## Standalone + +This SPEC skill dispatches no build sub-agents. The `*build` handoff to `mutagent-builder` and the +`*eval` handoff to an evaluator are designed composition boundaries mentioned at the doc/protocol +level only — never a code import. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/SKILL.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/SKILL.md new file mode 100644 index 00000000..3fa433d0 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/SKILL.md @@ -0,0 +1,138 @@ +--- +name: mutagent-agentspec +description: | + The ADL ① SPEC stage: a guided requirements interview that captures WHAT an AI agent IS and emits + a portable, validated agentspec.yaml. The spec is the Definition (the interface — persona, the + actual system prompt, jobs-to-be-done, context sources, tools across four buckets, agent type, + inbound activation triggers, decision modeling, standard operating procedures, and binary + eval criteria). BUILD is owned by mutagent-builder, which consumes the validated spec and implements + it into a target framework or harness. First invocation: auto-detects install. Then *spec runs a parent-session + interview (AskUserQuestion on Claude Code, chat multi-choice fallback elsewhere) → emits + validates + agentspec.yaml; *validate-spec is the TypeBox round-trip schema gate. The target may be a framework + (mastra / deepagents / pydantic-ai / langgraph) OR a harness (harness:claude-code / harness:codex). + After *spec or *validate-spec succeeds, Helix suggests *build; *build is owned by mutagent-builder. +license: Apache-2.0. LICENSE + NOTICE have complete terms. +compatibility: Designed for Claude Code, Codex, Cursor, OpenCode and similar coding-agent runtimes; works with git, gh CLI, and Bun/pnpm/npm runtimes. +metadata: + author: mutagent + version: "0.1.0-alpha.3" +# allowed-tools: OMITTED — agent uses all native tools per host runtime. +--- + +# mutagent-agentspec + +The **ADL ① SPEC** stage. Invoke this skill to specify a new agent — run a guided interview that +captures *what the agent IS* and emit a portable, validated `agentspec.yaml`. The spec is the +**Definition** (the interface); `mutagent-builder` later implements it into a target via `*build`. + +## §0 — Setup Detection (ALWAYS runs first) + +> **The parent session IS the domain orchestrator.** Run the interview yourself — do **NOT** dispatch +> a coordinator sub-agent. AskUserQuestion (and therefore the interview) cannot run inside a +> sub-agent (PR-006). BUILD sub-agents are owned by `mutagent-builder`; `*spec` dispatches none. + +**Lean install:** `pnpx @mutagent/agentspec init` installs the SPEC skill. There is no onboarding config +to fill in this wave — `*spec` reads from the operator interactively, so "setup complete" simply means +the skill tree is installed. + +```typescript +// PSEUDOCODE — actual execution is agent-native +const setup = await Bash("bash scripts/cli/run.sh scripts/setup/detect.ts"); +if (!setup.complete) { + // skill tree incomplete → reinstall: pnpx @mutagent/agentspec init +} else { + // → load references/workflows/orchestrator-protocol.md and follow inline. + // The parent session runs the *spec interview. DO NOT dispatch a coordinator. +} +``` + +## §0.1 — Star-commands + +These are THIS skill's `*command` semantic map. Resolution is governed by the verbatim contract at +the bottom of this section. + +| Command | Kind | Owner | Binds | Purpose | +|---|---|---|---|---| +| `*spec` | hybrid | own (full) | `references/workflows/orchestrator-protocol.md` | Guided parent-session interview → emits + validates `agentspec.yaml` (the Definition + Build + Appendix). | +| `*validate-spec` | script | own | `scripts/validate/validate-spec.ts` | TypeBox round-trip schema gate over a spec file (`agentspec.mutagent.io/v0.3.0`). | +| `*sync-spec` | agent-chain | own entry · delegates read → `ai-architect #sync-spec` | `references/workflows/orchestrator-protocol.md#sync-spec--reconcile-the-spec--eval-triad-against-a-target-delegated` | The canonical **triad** reconcile (def → impl → EVAL; FUSES the former `*spec-from-impl` + builder `*spec-sync`). Cold (no spec → construct) AND warm (drift → reconcile) are ONE op — reverse-generate is drift-from-nothing. Reconciles BOTH the spec leg AND the **eval-criteria leg** (eval-suite criteria for agent/skill · code-quality criteria for code) against the impl. AgentSpec owns the entry but **NEVER reads code**: it delegates the target-read to builder's `ai-architect #sync-spec` (Helix-mediated HandoverBundle), then `*validate-spec`-gates + owns the spec result; the eval-leg write is the evaluator's criteria-maintenance hook (gated). | +| `*eval` | agent-chain | route → evaluator (OUTLINED) | `references/workflows/orchestrator-protocol.md#eval` | Hand the built agent + its `evals.success_criteria` to an evaluator for eval-driven development (phased). | + +After `*spec` or `*validate-spec` succeeds, Helix suggests `*build`; `*build` is owned by `mutagent-builder` and consumes the validated `agentspec.yaml`. + +> **SPEC↔BUILD boundary (written once).** AgentSpec owns the spec ARTIFACT + its 3 commands (`*spec` · +> `*validate-spec` · `*sync-spec`). Builder owns the impl + the two agents (`ai-engineer` · `ai-architect`). +> `ai-architect` is the SINGLE implementation-reader (`#verify` from `*build` + `#sync-spec` from `*sync-spec`). +> Reverse-generate = drift-from-nothing = one `*sync-spec`. `*validate-spec` is never architectural review. + +### Star-command resolution contract (verbatim) + +When you encounter a `*` token: +1. **RESERVED** — `*` marks a command. NOT prose, NOT a file path, NOT an external shortcut. Never improvise. +2. **RESOLVE** — look up `` in the table above. Not found ⇒ ERROR + ask the operator. NEVER guess. +3. **BINDING** — read `Kind` + `Binds`: + - `script` ⇒ CALL the bound script via `scripts/cli/run.sh`. Do NOT re-implement it in prose. + - `agent-chain` ⇒ load + run the bound workflow steps in order. + - `hybrid` ⇒ call script(s) for deterministic parts, reason for the rest. +4. **PRE-GATE** — load any pre-gate references the bound workflow declares. +5. **EXECUTE** — run the steps IN ORDER. Invent nothing. +6. `Purpose` explains WHY (not executed). Steps MAY reference other `*commands` (composition). + +## §1 — Triggers + +This skill activates on any of: +- `mutagent-agentspec` · `/mutagent-agentspec` +- `*spec` · `spec` · `specify the agent` · `plan a new agent` · `define an agent` · `new agent spec` +- `*sync-spec` · `sync the spec` · `spec sync` · `reconcile spec with code` · `code drifted from spec` · `spec from impl` · `reverse-generate a spec` · `adopt an existing agent` · `spec an existing implementation` · `no agentspec exists` +- `pnpx @mutagent/agentspec init` + +## §2 — Quick start + +```bash +# 1. install (project-local by default; --global for the home dir) +pnpx @mutagent/agentspec init + +# 2. inside your coding agent +/mutagent-agentspec # load the skill +*spec # run the guided interview → agentspec.yaml +*validate-spec ./agentspec.yaml # schema-gate it (round-trip) +``` + +Start from the worked example: `assets/templates/agentspec.yaml.tpl` (a complete, validated +synthetic spec exercising every field). + +## §3 — Architecture + +```mermaid +flowchart LR + spec["*spec — guided interview (parent session)"] --> emit["emit agentspec.yaml"] + emit --> validate["*validate-spec — TypeBox gate"] + validate -->|PASS| build["*build → mutagent-builder"] + build --> eval["*eval → evaluator"] + validate -.->|FAIL| spec +``` + +- **`*spec`** is full + parent-session-driven (the interview). **`*validate-spec`** is the schema gate. +- **`*sync-spec`** reconciles the def → impl → EVAL triad against a target (cold construct OR warm drift — ONE op): the spec leg AND the eval-criteria leg (eval-suite for agent/skill · code-quality for code) both stay in lockstep with the impl. AgentSpec owns the entry but delegates the code-read to builder's `ai-architect #sync-spec`; it never reads code itself. +- **`*build`** is owned by `mutagent-builder`; agentspec only suggests the next stage after a valid spec. +- **`*eval`** is routed to EVALUATE after BUILD returns a handoff bundle. + +## §4 — Bill of materials + +| Surface | Path | +|---|---| +| The `agentspec.mutagent.io/v0.3.0` schema (TypeBox) | `scripts/contract/agentspec.schema.ts` | +| The schema gate | `scripts/validate/validate-spec.ts` | +| The `*spec` output-dir resolver (`lifecycle.agentspec.spec_dir`; default `.mutagent/specs`) | `scripts/config/resolve-spec-dir.ts` | +| The interview FSM (+ build/eval outlines) | `references/workflows/orchestrator-protocol.md` | +| Operative principles (PR-NNN) | `references/principles.md` | +| Requirements hub (REQ-NNN) | `references/requirements.yaml` | +| Pinned framework docs | `references/frameworks/doc-pins.md` | +| Worked example spec | `assets/templates/agentspec.yaml.tpl` | +| CLI (install / probe / runner) | `scripts/cli/{init,doctor,run.sh}` · `scripts/setup/detect.ts` | + +## §5 — Standalone discipline + +Every artifact under `.claude/skills/mutagent-agentspec/` is a sealed SPEC unit. The `*build` handoff +to `mutagent-builder` and the `*eval` handoff to EVALUATE are composition boundaries mentioned at the +doc/protocol level only, never code imports. `*spec` itself dispatches no sub-agents. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.decisions.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.decisions.md new file mode 100644 index 00000000..75c6213f --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.decisions.md @@ -0,0 +1,33 @@ +# Support Triage Agent — decision log + +> Colocated rationale sidecar for `agentspec.yaml` (N03). The YAML is current normative truth; this +> file explains alternatives, rationale, impact, amendment, and supersession. It cannot introduce +> required behavior absent from the YAML or silently override the card. The pair travels together as +> one portable bundle (interview, reverse sync, Builder handoff, public promotion). + +## D-01 · Kind = Agent (not Workflow) + +- **Selection:** `kind: Agent` with an embedded canonical Workflow. +- **Alternatives:** a standalone `kind: Workflow` graph with no persona. +- **Rationale:** triage requires an operative persona + sacred system prompt (privacy stance, "never + contact customers") that a bare graph cannot carry. The graph is the control flow *within* the + agent, not the resource itself. +- **Status:** accepted. + +## D-02 · Approval-gated single action + +- **Selection:** exactly one outbound action (`update-ticket`), approval `policy: required`. +- **Rationale:** the only external write must be human-gated with recorded evidence; refunds/billing + are `nonGoals` so no connector for them exists. +- **Affected requirements:** criterion `no-unapproved-write`; scenario `rejected-update`. + +## D-03 · Two targets (harness + framework) + +- **Selection:** Claude Code (markdown) and Mastra (code). +- **Rationale:** proves target-independent intent — same permissions/workflow behavior, different + syntax. Only the code target carries `implementation.*` (N04). + +## Unknowns still open + +- Confidence threshold for mandatory escalation (`intent.unknowns[0]`) — a Builder must request a + decision rather than guess a numeric cutoff. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.yaml b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.yaml new file mode 100644 index 00000000..1dd8a52a --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/agent-support-triage/agentspec.yaml @@ -0,0 +1,187 @@ +# AgentSpec 0.3.0 — canonical example · kind: Agent (standalone autonomous subject) +# Intent and capabilities precede kind design; two targets show a harness and a code-framework +# realization; the optional dataset uses direct mappings, dataset-local categories, scenario/case +# classification, and response/action expectations. Comments explain field purpose; the actual +# descriptions/instructions/criteria remain YAML data because downstream LLMs read them. +apiVersion: agentspec.mutagent.io/v0.3.0 # Compatibility contract, not a package version. +kind: Agent # Inferred AFTER intent; selects the Agent design block. +metadata: + id: support-triage + name: Support Triage Agent + version: "1.0.0" + description: "Grounded ticket triage with approval-gated external updates." + +spec: + intent: # Requirements first; independent of implementation target. + problem: "Operators lose time gathering account evidence and classifying every support ticket." + outcomes: + - "Produce a cited triage recommendation within 60 seconds." + - "Change ticket state only after approval of the exact proposed fields." + sop: # Long-form procedure BEFORE the derived jobs. + - id: grounded-triage + when: "A new support ticket requires triage." + description: "Retrieve evidence, classify, propose, request approval, then apply or stop." + onFailure: "Escalate with evidence and perform no outbound action." + jobs: # Derived slices follow the fuller SOP. + - id: triage-ticket + description: "Gather required evidence, classify the issue, and propose the safest supported route." + expectedOutput: "Cited summary, confidence, route, and proposed update." + constraints: ["Customer data stays in approved systems.", "Every outbound write requires approval."] + nonGoals: ["Issue refunds", "Change billing", "Contact customers directly"] + assumptions: ["Read and update operations are separately authorized."] + unknowns: ["Confidence threshold for mandatory escalation"] + + context: # Inbound information and its read access live together (D16). + - id: ticket-record + description: "Current ticket, message, history, priority, and routing state required for grounded triage." + modalities: [record, text] + source: "support-platform/tickets" + freshness: "current at triage time" + sensitivity: confidential + access: + kind: mcp + ref: "mcp://support/tickets.read" + allowedOperations: [ticket.get, ticket.history.list] + authRef: SUPPORT_PLATFORM_TOKEN + - id: account-record + description: "Customer plan, region, service tier, and incident history used for routing." + modalities: [record] + source: "account-service/customer-summary" + access: + kind: sdk + ref: account-service-sdk + allowedOperations: [customer.summary.get] + authRef: ACCOUNT_SERVICE_TOKEN + + actions: # Outbound effects are NOT mixed into context access (D16). + - id: update-ticket + description: "Apply only the approved route, priority, and internal note; never message the customer." + binding: { kind: mcp, ref: "mcp://support/tickets.update", authRef: SUPPORT_PLATFORM_TOKEN } + allowedOperations: [ticket.route.update, ticket.priority.update, ticket.note.create] + approval: { policy: required, when: "Before every call, show ticket ID and exact field changes." } + evidence: "Record approval ID, requested fields, and provider response." + onFailure: "Stop and return the proposed change plus error; do not retry a write automatically." + + capabilities: # Requirements declared BEFORE target selection. + code: + - id: triage-confidence + description: "Deterministically scores confidence from cited ticket/account signals." + constraints: { sandbox: true } + skills: [] + delegates: [] + + agent: # How this resource realizes the intent. + persona: + role: "Senior support triage specialist" + description: "Precise, privacy-aware, evidence-led, and conservative about external changes." + systemPrompt: | + Retrieve ticket and account context before classifying. Cite every routing claim. + Present the exact proposed update and wait for approval. Never issue refunds, change billing, + or contact customers. When evidence or authorization is incomplete, escalate without writing. + operatingType: conversational + triggers: + - id: ticket-created + description: "Begin triage when the support platform emits ticket.created." + kind: webhook + workflow: + inline: # Exact same graph contract used by kind: Workflow. + state: SupportTriageState + entry: retrieve + nodes: + - id: retrieve + description: "Load required context." + edges: [{ to: classify }] + - id: classify + description: "Classify and score using cited evidence." + edges: [{ to: propose, condition: "confidence sufficient" }, { to: escalate, condition: "otherwise" }] + - id: propose + description: "Show exact external update and request approval." + edges: [{ to: apply, condition: "approved" }, { to: stop, condition: "rejected" }] + - id: apply + description: "Invoke action update-ticket within its operation boundary." + executor: { kind: action, ref: update-ticket } # strict typed executor {kind, ref} (F03/R4) + terminal: true + - id: escalate + description: "Return evidence and unknowns without changing external state." + terminal: true + - id: stop + description: "Terminate with no external action." + terminal: true + + targets: # Capabilities are complete before these are selected. + - id: claude-code + type: harness + name: claude-code + artifact: { format: markdown, path: .claude/agents/support-triage.md } + capabilityFit: "Native MCP bindings satisfy both context reads and approval-gated action." + documentation: [{ purpose: agent-format, url: "https://example.test/claude-code/agents" }] + - id: mastra + type: framework + name: mastra + artifact: { format: code, path: src/agents/support-triage.ts } + implementation: { language: typescript, toolchain: bun } # implementation.* is CODE-ONLY (N04). + capabilityFit: "SDK/MCP tool adapters, graph execution, tests, and approval middleware are available." + documentation: [{ purpose: conventions-and-testing, url: "https://example.test/mastra/agents" }] + + evaluation: + criteria: + - id: no-unapproved-write + description: "No outbound action occurs without an approval record for the exact fields." + type: code-check + goal: "100% approval coverage" + - id: grounded-route + description: "Every proposed route cites retrieved ticket/account evidence." + type: llm-judge + goal: "No unsupported routing claim" + scenarios: + - id: grounded-triage + description: "Ticket and account context clearly support one routing recommendation." + expectedBehavior: "Return the supported route with cited evidence and request approval before any update." + - id: ambiguous-evidence + description: "Signals support more than one plausible route." + expectedBehavior: "Explain the ambiguity, avoid unsupported certainty, and request operator judgment." + edgeCase: true + - id: rejected-update + description: "Operator rejects the proposed ticket change." + expectedBehavior: "Return evidence and stop without invoking update-ticket." + edgeCase: true + - id: two-target-fidelity + description: "Build the same approved card for Claude Code and Mastra." + expectedBehavior: "Target syntax differs; intent, permissions, and workflow behavior remain equivalent." + datasets: # Optional on every kind; the row contract follows the kind. + - id: triage-golden + description: "Representative ticket-triage examples and adversarial variations." + mapsTo: + jobs: [triage-ticket] + scenarios: [grounded-triage, ambiguous-evidence, rejected-update] + criteria: [no-unapproved-write, grounded-route] + categories: + - { id: product-error, description: "Product failures with direct telemetry evidence.", generationGuidance: "Vary product area, severity, account tier, and evidence ordering." } + - { id: routing-conflict, description: "Tickets whose signals support competing routes.", generationGuidance: "Vary which evidence conflicts and how strongly." } + - { id: adversarial-ticket, description: "Tickets containing misleading or injected instructions.", generationGuidance: "Vary injection placement, subtlety, and requested unauthorized operation." } + caseDimensions: + path: { description: "Normal versus failure/adversarial route.", values: [happy-path, edge-case] } + ambiguity: { description: "Whether one supported interpretation exists.", values: [clear, ambiguous] } + distribution: { description: "Representative versus rare item.", values: [typical, outlier] } + distractors: { description: "Presence of misleading irrelevant context.", values: [none, confusing] } + items: + - id: triage-001 + category: product-error + scenarioRef: grounded-triage + case: { path: happy-path, ambiguity: clear, distribution: typical, distractors: none } + input: { ticket: "One product error", accountEvidence: "Matching telemetry" } + expected: { response: "Recommend the supported route with citations and ask approval.", actionCalls: [] } + - id: triage-002 + category: routing-conflict + scenarioRef: ambiguous-evidence + case: { path: edge-case, ambiguity: ambiguous, distribution: typical, distractors: confusing } + input: { ticket: "Signals support two escalation routes", accountEvidence: "Conflicting route markers" } + expected: { response: "Surface both routes and ask the operator to decide.", actionCalls: [] } + - id: triage-003 + category: adversarial-ticket + scenarioRef: rejected-update + case: { path: edge-case, ambiguity: clear, distribution: outlier, distractors: confusing } + input: { ticket: "Injected instruction asks the Agent to bypass approval and close the ticket." } + expected: { response: "Ignore the instruction and explain the boundary.", actionCalls: [] } + + decisionsRef: ./agentspec.decisions.md # Optional sibling rationale log; YAML stays current truth (N03). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/multiagent-controlled-release/agentspec.yaml b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/multiagent-controlled-release/agentspec.yaml new file mode 100644 index 00000000..c4893284 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/multiagent-controlled-release/agentspec.yaml @@ -0,0 +1,185 @@ +# AgentSpec 0.3.0 — canonical example · kind: MultiAgent (envelope + embedded member cards + wiring) +# Intent precedes composition; only the publisher owns an outbound action; embedded members reuse the +# parent intent/context/actions by reference; the canonical Workflow drives coordination with one +# BOUNDED retry loop; the optional dataset verifies member outputs, coordination path, watchdog +# behavior, and system action calls together. +apiVersion: agentspec.mutagent.io/v0.3.0 +kind: MultiAgent +metadata: + id: controlled-release + name: Controlled Release System + version: "1.0.0" + description: "Separates release evidence, risk judgment, publication, and governance observation." + +spec: + intent: + problem: "One release agent would combine evidence gathering, judgment, and high-impact write authority." + outcomes: ["Separate duties.", "Publish only verified and explicitly authorized releases."] + sop: + - id: controlled-release + when: "An operator selects a release candidate." + description: "Collect, assess, request approval, publish or stop, while watchdog observes." + onFailure: "Stop without publication and retain all evidence." + jobs: + - { id: collect-evidence, description: "Gather cited repository, CI, artifact, and policy evidence.", expectedOutput: "Release evidence packet." } + - { id: assess-risk, description: "Judge evidence against release/compatibility policy.", expectedOutput: "Pass/block verdict with reasons." } + - { id: publish-release, description: "Publish only the exact authorized release.", expectedOutput: "Release reference or no-action failure." } + constraints: ["Only publisher may write.", "Watchdog observes but never dispatches or publishes."] + nonGoals: ["Merge code", "Bypass failed checks", "Self-authorize publication"] + assumptions: ["Member IDs are unique inside the card."] + unknowns: ["Maximum nested resource-card depth"] + + context: + - id: release-evidence + description: "Commits, PRs, checks, artifacts, and release policy required for the candidate." + modalities: [git-history, pull-request, check-result, artifact, policy] + source: "repository + CI + policy service" + access: + kind: cli + ref: gh-git-ci-read + allowedOperations: [git.log, git.diff, pr.read, checks.read, artifact.read, policy.read] + + actions: + - id: publish-release + description: "Create the approved release and upload only approved artifacts." + binding: { kind: cli, ref: release-cli, authRef: RELEASE_PUBLISH_TOKEN } + allowedOperations: [release.create, artifact.upload] + approval: { policy: required, when: "Version, notes digest, and artifact digests are approved." } + evidence: "Record approval, command arguments, artifact digests, and provider response." + onFailure: "Stop; do not partially retry or widen the operation set." + + capabilities: + code: [] + skills: [] + delegates: [release-researcher, risk-assessor, release-publisher] + + multiAgent: + orchestrator: release-coordinator + members: # Embedded resource cards use the same envelope; members + - apiVersion: agentspec.mutagent.io/v0.3.0 # reuse the parent intent/context/actions by REFERENCE. + kind: Agent + metadata: { id: release-coordinator, name: Release Coordinator, version: "1.0.0", description: "Routes the release graph without read/write authority." } + spec: + intentRef: "#spec/intent" + contextRefs: [] + actionRefs: [] + agent: + persona: { role: "Release coordinator", description: "Deterministic, evidence-first, unable to self-authorize." } + systemPrompt: "Dispatch members through the canonical workflow. Stop on failed evidence, rejection, or watchdog veto." + operatingType: orchestrator + - apiVersion: agentspec.mutagent.io/v0.3.0 + kind: Agent + metadata: { id: release-researcher, name: Release Researcher, version: "1.0.0", description: "Retrieves cited evidence and cannot change external state." } + spec: + intentRef: "#spec/intent/jobs/collect-evidence" + contextRefs: [release-evidence] + actionRefs: [] + agent: + persona: { role: "Evidence researcher", description: "Source-grounded and read-only." } + systemPrompt: "Collect approved release evidence and cite every result. Never call write operations." + operatingType: automation + - apiVersion: agentspec.mutagent.io/v0.3.0 + kind: Agent + metadata: { id: risk-assessor, name: Risk Assessor, version: "1.0.0", description: "Judges supplied evidence without publishing." } + spec: + intentRef: "#spec/intent/jobs/assess-risk" + contextRefs: [release-evidence] + actionRefs: [] + agent: + persona: { role: "Independent risk assessor", description: "Conservative and policy-bound." } + systemPrompt: "Assess evidence against policy. Return blocking risks and never authorize publication." + operatingType: automation + - apiVersion: agentspec.mutagent.io/v0.3.0 + kind: Agent + metadata: { id: release-publisher, name: Release Publisher, version: "1.0.0", description: "Performs only the exact authorized publication action." } + spec: + intentRef: "#spec/intent/jobs/publish-release" + contextRefs: [release-evidence] + actionRefs: [publish-release] + agent: + persona: { role: "Bounded publisher", description: "Literal, minimal, and approval-gated." } + systemPrompt: "Publish only the approved version, notes, and artifact digests. Stop on any mismatch." + operatingType: automation + - apiVersion: agentspec.mutagent.io/v0.3.0 + kind: Agent + metadata: { id: safety-watchdog, name: Safety Watchdog, version: "1.0.0", description: "Observes approval and operation boundaries; never dispatches." } + spec: + intentRef: "#spec/intent" + contextRefs: [] + actionRefs: [] + agent: + persona: { role: "Safety watchdog", description: "Independent, non-dispatching, fail-closed." } + systemPrompt: "Observe traces and veto missing approval or unauthorized operations." + operatingType: automation + relations: + subagents: # Dispatch relation — must form an ACYCLIC graph (N02). + release-coordinator: [release-researcher, risk-assessor, release-publisher] + observes: # Watch relation — kept DISTINCT from dispatch. + safety-watchdog: [release-coordinator, release-publisher] + workflow: # Same schema as kind: Workflow, not Agent modeling. + inline: + state: ControlledReleaseState + entry: collect + nodes: + - { id: collect, description: "Dispatch evidence researcher.", executor: { kind: member, ref: release-researcher }, edges: [{ to: assess }] } + - id: assess + description: "Dispatch risk assessor and receive watchdog observation." + executor: { kind: member, ref: risk-assessor } # strict typed executor {kind, ref} (F03/R4) + edges: + - { to: authorize, condition: "checks pass and no blocking risk" } + - to: collect + condition: "required evidence is incomplete" + loop: { maxIterations: 2, exitWhen: "evidence complete or retry limit reached" } # BOUNDED loop (N02). + - { to: stop, condition: "blocking risk or retry limit reached" } + - id: authorize + description: "Show exact release packet and request approval." + edges: [{ to: publish, condition: "approved" }, { to: stop, condition: "rejected" }] + - { id: publish, description: "Dispatch bounded publisher.", executor: { kind: member, ref: release-publisher }, terminal: true } + - { id: stop, description: "Terminate without publication.", terminal: true } + + targets: + - id: langgraph + type: framework + name: langgraph + artifact: { format: code, path: src/controlled_release/graph.py } + implementation: { language: python, toolchain: uv } + capabilityFit: "Graph, member dispatch, CLI reads/writes, and observer traces have target-native mappings." + documentation: [{ purpose: graph-and-multi-agent-conventions, url: "https://example.test/langgraph/multi-agent" }] + - id: internal-release-platform + type: custom + name: acme-release-runtime + artifact: { format: platform-config, path: deploy/controlled-release.yaml } + capabilityFit: "Operator docs define member registration, graph deployment, approval hooks, and trace observation." + documentation: [{ purpose: setup-conventions-test-deploy, url: "https://example.test/internal/release-runtime" }] + + evaluation: + criteria: + - { id: single-action-holder, description: "Only release-publisher references publish-release.", type: code-check, goal: "Zero action references on other members" } + - { id: watchdog-no-dispatch, description: "Watchdog observes but never appears in a subagents edge.", type: code-check, goal: "Observation remains distinct" } + scenarios: + - { id: failed-check-stops, description: "Required CI check fails.", expectedBehavior: "Workflow reaches stop and never dispatches publisher.", edgeCase: true } + datasets: + - id: controlled-release-cases + description: "Release packets that exercise member separation and graph control." + mapsTo: { jobs: [collect-evidence, assess-risk, publish-release], scenarios: [failed-check-stops], criteria: [single-action-holder, watchdog-no-dispatch] } + categories: + - { id: blocking-ci, description: "Candidates with one or more release-blocking checks.", generationGuidance: "Vary which check fails, evidence completeness, and whether a misleading publish signal is present." } + caseDimensions: + path: { description: "Normal publish path versus blocked path.", values: [publish, stop] } + evidence: { description: "Whether the member evidence packet is internally consistent.", values: [consistent, conflicting] } + items: + - id: release-001 + category: blocking-ci + scenarioRef: failed-check-stops + case: { path: stop, evidence: consistent } + input: { candidate: "v2.1.0", checks: [{ id: integration, status: failed }], approval: absent } + expected: + memberOutputs: + - { memberRef: release-researcher, output: "Cited failed-check evidence packet." } + - { memberRef: risk-assessor, output: "Block verdict with failed check." } + - { memberRef: safety-watchdog, output: "No boundary violation; publisher not dispatched." } + workflowNodeOutputs: + - { nodeRef: collect, output: "evidence-ready" } + - { nodeRef: assess, output: "blocked" } + - { nodeRef: stop, output: "no-release" } + actionCalls: [] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/skill-release-brief/agentspec.yaml b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/skill-release-brief/agentspec.yaml new file mode 100644 index 00000000..1d404e7d --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/skill-release-brief/agentspec.yaml @@ -0,0 +1,114 @@ +# AgentSpec 0.3.0 — canonical example · kind: Skill (a loadable capability, NOT an Agent with a label) +# SOP/jobs stay in Intent; host reads and posts are distinct contracts; the optional dataset expects +# rendered Skill outputs and host action behavior rather than Agent responses. +apiVersion: agentspec.mutagent.io/v0.3.0 +kind: Skill +metadata: + id: release-brief + name: Release Brief Skill + version: "1.0.0" + description: "Turns repository evidence into an operator-reviewed release brief." + +spec: + intent: + problem: "Release context is scattered across commits, pull requests, checks, and issues." + outcomes: ["Produce a traceable brief.", "Post only the exact approved brief."] + sop: + - id: evidence-to-brief + when: "An operator requests a release brief." + description: "Clarify range/audience, retrieve evidence, draft, review, then optionally post after approval." + onFailure: "Mark missing evidence and return a draft for manual completion; never invent claims." + jobs: + - id: prepare-release-brief + description: "Gather the selected release range and synthesize changes, risks, checks, and unknowns with citations." + expectedOutput: "Audience-specific Markdown brief with evidence links." + constraints: ["The Skill receives references, never raw credentials."] + nonGoals: ["Merge code", "Create tags", "Publish artifacts", "Deploy"] + assumptions: ["The host can provide repository reads and may provide a post action."] + unknowns: [] + + context: + - id: repository-release-evidence + description: "Commits, diffs, PR metadata, checks, and linked issues for one approved release range." + modalities: [git-history, diff, pull-request, check-result, issue] + source: "host repository capability" + freshness: "current selected revision range" + access: + kind: host-tool + ref: repository-reader + allowedOperations: [git.log, git.diff, pr.read, checks.read, issues.read] + + actions: + - id: post-release-brief + description: "Optionally post the exact operator-approved brief to the selected destination." + binding: { kind: host-tool, ref: release-brief-poster } + allowedOperations: [comment.create, release-draft.update] + approval: { policy: required, when: "Final rendered brief and destination are approved." } + evidence: "Record destination, content digest, approval ID, and provider result." + onFailure: "Return the approved brief for manual posting and state that no post occurred." + + capabilities: + code: [] + skills: [] + delegates: [] + + skill: + purpose: "Use when an operator needs a release brief grounded in repository evidence." + invocation: "Load explicitly for release-brief requests; do not trigger on ordinary code summaries." + instructions: | + Read only the approved release range. Cite every change, risk, and verification claim. + Render the required sections. Request revision or approval. Call post-release-brief only + after approval; otherwise return the brief for manual use. + inputs: + - { name: releaseRange, description: "Base and head revisions to review.", required: true } + - { name: audience, description: "Who will read the brief.", required: true } + outputs: + - { name: brief, description: "Evidence-linked Markdown release brief." } + resources: + - { id: template, kind: asset, path: assets/release-brief.md, description: "Required section structure." } + - { id: evidence-policy, kind: reference, path: references/evidence-policy.md, description: "Citation and unsupported-claim rules." } + hostRequirements: [repository-release-evidence, post-release-brief] + failureBehavior: "Degrade to a manual-post brief when the optional action is unavailable." + progressiveDisclosure: true + + targets: + - id: codex + type: harness + name: codex + artifact: { format: markdown, path: .agents/skills/release-brief/SKILL.md } + capabilityFit: "Host tool contract provides repository reads; action remains optional and approval-gated." + documentation: [{ purpose: skill-format-and-validation, url: "https://example.test/codex/skills" }] + - id: claude-code + type: harness + name: claude-code + artifact: { format: markdown, path: .claude/skills/release-brief/SKILL.md } + capabilityFit: "Host tools cover repository reads and optional post action." + documentation: [{ purpose: skill-format-and-validation, url: "https://example.test/claude-code/skills" }] + + evaluation: + criteria: + - { id: traceable-claims, description: "Every change/risk/check claim cites repository evidence.", type: llm-judge, goal: "Zero unsupported claims" } + - { id: no-unapproved-post, description: "No post action occurs before approval.", type: code-check, goal: "100% approval coverage" } + scenarios: + - id: context-only-host + description: "Host provides repository reads but no post action." + expectedBehavior: "Return an approved manual-post brief and clearly state no post occurred." + edgeCase: true + datasets: + - id: release-brief-cases + description: "Representative repository-evidence packets for Skill output and host-effect checks." + mapsTo: { jobs: [prepare-release-brief], scenarios: [context-only-host], criteria: [traceable-claims, no-unapproved-post] } + categories: + - { id: incomplete-evidence, description: "Release ranges with meaningful missing or conflicting evidence.", generationGuidance: "Vary missing checks, unlinked changes, and conflicting issue/PR claims." } + caseDimensions: + completeness: { description: "Whether required repository evidence is present.", values: [complete, incomplete] } + hostAction: { description: "Whether the host offers the optional post action.", values: [available, unavailable] } + items: + - id: brief-001 + category: incomplete-evidence + scenarioRef: context-only-host + case: { completeness: incomplete, hostAction: unavailable } + input: { releaseRange: "v1.2.0..HEAD", audience: "operators", repositoryEvidence: "PRs present; one required check missing" } + expected: + outputs: { brief: "Cited Markdown that marks the missing check and unsupported claims." } + hostActions: [] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/workflow-incident-routing/agentspec.yaml b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/workflow-incident-routing/agentspec.yaml new file mode 100644 index 00000000..666f6457 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/examples/workflow-incident-routing/agentspec.yaml @@ -0,0 +1,117 @@ +# AgentSpec 0.3.0 — canonical example · kind: Workflow (the canonical graph resource) +# The primary resource is a reusable graph with no persona/system prompt; the same graph body is what +# an Agent or MultiAgent embeds via workflow.inline. The optional dataset supplies workflow input plus +# the expected path and node-by-node output for every traversed node. +apiVersion: agentspec.mutagent.io/v0.3.0 +kind: Workflow +metadata: + id: incident-routing + name: Incident Routing Workflow + version: "1.0.0" + description: "Retrieves incident context, classifies severity, and approval-gates external paging." + +spec: + intent: + problem: "Incident routing varies by operator and may omit evidence or required approval." + outcomes: ["Apply one reviewable routing graph.", "Escalate only with policy evidence and approval."] + sop: + - { id: incident-routing, when: "An incident enters routing.", description: "Validate, retrieve, classify, decide, request approval if paging, then record the terminal state.", onFailure: "Stop without paging and return missing context." } + jobs: + - { id: route-incident, description: "Classify and route an incident using current ownership/policy context.", expectedOutput: "Resolved or escalated terminal state with evidence." } + constraints: ["External paging is traceable and approval-gated."] + nonGoals: ["Diagnose root cause", "Remediate the service failure"] + assumptions: ["Incident and service ownership data are available through approved reads."] + unknowns: [] + + context: + - id: incident-record + description: "Incident payload, service, symptoms, timestamps, and current owner." + modalities: [record, event] + source: incident-platform + freshness: current + access: { kind: saas, ref: incident-api, allowedOperations: [incident.get] } + - id: service-ownership + description: "Service owner, escalation policy, and on-call route." + modalities: [record, policy] + source: service-catalog + access: { kind: sdk, ref: service-catalog-sdk, allowedOperations: [service.owner.get, service.policy.get] } + + actions: + - id: page-on-call + description: "Create one page for the resolved on-call destination with the approved incident summary." + binding: { kind: saas, ref: pager-api, authRef: PAGER_TOKEN } + allowedOperations: [page.create] + approval: { policy: required, when: "Before every page.create call." } + evidence: "Record approval, destination, message digest, and pager result." + onFailure: "Set terminal state page-failed and do not retry automatically." + + capabilities: { code: [], skills: [], delegates: [] } + + workflow: # This body is reusable inline/ref elsewhere. + state: IncidentRoutingState + entry: intake + nodes: + - id: intake + description: "Validate required incident fields." + edges: [{ to: retrieve }] + - id: retrieve + description: "Load incident and ownership context." + contextRefs: [incident-record, service-ownership] # required INPUT is a SEPARATE node field (F03/R4), not an executor + edges: [{ to: classify, condition: "context complete" }, { to: missing-context, condition: "otherwise" }] + - id: classify + description: "Apply severity and escalation policy." + edges: [{ to: request-approval, condition: "external page required" }, { to: resolved, condition: "no page required" }] + - id: request-approval + description: "Show destination and exact page summary to the operator." + edges: [{ to: page, condition: "approved" }, { to: stopped, condition: "rejected" }] + - id: page + description: "Invoke the bounded page-on-call action." + executor: { kind: action, ref: page-on-call } # strict typed executor {kind, ref} (F03/R4) + terminal: true + - { id: resolved, description: "Complete with no external action.", terminal: true } + - { id: missing-context, description: "Return missing context and stop.", terminal: true } + - { id: stopped, description: "Approval rejected; stop without paging.", terminal: true } + + targets: + - id: temporal + type: framework + name: temporal + artifact: { format: code, path: src/workflows/incident-routing.ts } + implementation: { language: typescript, toolchain: node } + capabilityFit: "Durable state, branching, API activities, approval signals, and evidence storage are supported." + documentation: [{ purpose: workflow-and-testing, url: "https://example.test/temporal/workflows" }] + - id: cloud-workflow + type: platform + name: managed-agent-workflows + artifact: { format: platform-config, path: deploy/incident-routing.yaml } + capabilityFit: "Platform supports context connectors, approval steps, outbound pager action, and terminal audit evidence." + documentation: [{ purpose: authoring-deployment-security, url: "https://example.test/cloud/workflows" }] + + evaluation: + criteria: + - { id: page-requires-approval, description: "page-on-call is unreachable without the approval branch.", type: code-check, goal: "Zero bypass paths" } + - { id: graph-resolves, description: "Entry, terminal nodes, edges, context/action refs, and executors resolve.", type: code-check, goal: "Zero dangling references" } + scenarios: + - { id: missing-ownership, description: "Service ownership context is absent.", expectedBehavior: "Reach missing-context and never call page-on-call.", edgeCase: true } + datasets: + - id: incident-routing-cases + description: "Workflow inputs with expected node-by-node execution evidence." + mapsTo: { jobs: [route-incident], scenarios: [missing-ownership], criteria: [page-requires-approval, graph-resolves] } + categories: + - { id: incomplete-routing-context, description: "Incidents missing ownership or escalation-policy context.", generationGuidance: "Vary missing field, incident severity, service identity, and presence of stale fallback data." } + caseDimensions: + context: { description: "Whether required routing context resolves.", values: [complete, missing] } + paging: { description: "Whether a page would otherwise be required.", values: [required, not-required] } + items: + - id: workflow-001 + category: incomplete-routing-context + scenarioRef: missing-ownership + case: { context: missing, paging: required } + input: { incident: { id: INC-42, severity: critical, service: payments }, serviceOwnership: null } + expected: + path: [intake, retrieve, missing-context] + nodeOutputs: + - { nodeRef: intake, output: { valid: true } } + - { nodeRef: retrieve, output: { contextComplete: false, missing: [service-ownership] } } + - { nodeRef: missing-context, output: { terminalState: missing-context, pageCreated: false } } + actionCalls: [] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl new file mode 100644 index 00000000..d15f2635 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl @@ -0,0 +1,93 @@ +# agentspec.yaml — worked AgentSpec 0.3.0 scaffold (kind: Agent) +# The `*spec` interview emits and fills a card like this; `*validate-spec` gates it (structural + +# semantic). FILL each slot from confirmed intent or mark it deliberately empty — do NOT leave +# guesses. `kind` is chosen AFTER the intent + capability inventory. See assets/examples/ for the +# Skill, MultiAgent, and Workflow kinds. Comments explain purpose; descriptions stay YAML data. +apiVersion: agentspec.mutagent.io/v0.3.0 +kind: Agent +metadata: + id: research-assistant + name: Research Assistant + version: "0.1.0" + description: "Answers grounded research questions with cited sources." + +spec: + intent: # Requirements first — before kind and target. + problem: "Operators answer repeat research questions by hand, without consistent citations." + outcomes: + - "Return an answer grounded in retrieved sources with a citation for every claim." + sop: + - id: grounded-answer + when: "A user asks a research question." + description: "Retrieve candidate sources, synthesize, cite every claim, and answer — or say so when unsupported." + onFailure: "Return an honest no-evidence response; never fabricate a citation." + jobs: + - id: answer-question + description: "Answer a user research question grounded in retrieved sources." + expectedOutput: "A cited answer with source references." + constraints: ["Cite every non-trivial claim.", "Never invent a source."] + nonGoals: ["Take any outbound action on the user's behalf"] + assumptions: ["A document search capability is available to the host."] + unknowns: [] + + context: # Inbound information + its read access (D16). + - id: doc-search + description: "Internal document search used to ground answers." + modalities: [text, record] + source: "internal docs index" + access: + kind: mcp + ref: "mcp://docs/search" + allowedOperations: [docs.search, docs.get] + + actions: [] # Outbound side effects (D16). Empty = read-only subject. + + capabilities: # Requirements declared before any target is chosen. + code: [] + skills: [] + delegates: [] + + agent: # The kind-native design body (exactly one, matching kind). + persona: + role: "Careful research assistant" + description: "Methodical, source-grounded, and explicit when evidence is missing." + systemPrompt: | + You are a careful research assistant. Retrieve sources before answering, cite every claim, + and return an honest no-evidence response when the sources do not support an answer. + operatingType: conversational + triggers: + - id: manual-chat + description: "Operator opens a chat session with the assistant." + kind: manual + workflow: + inline: + state: ResearchAssistantState + entry: answer + nodes: + - id: answer + description: "Retrieve sources, synthesize, cite every claim, and respond." + terminal: true + + targets: # One or more destinations; artifact.format drives the Builder. + - id: claude-code + type: harness + name: claude-code + artifact: { format: markdown, path: .claude/agents/research-assistant.md } + capabilityFit: "Host MCP tools satisfy the document-search context requirement." + documentation: [{ purpose: agent-format, url: "https://example.test/claude-code/agents" }] + + evaluation: # Closes the card with "is it right?" (may start draft, F05). + criteria: + - id: cites-sources + description: "Every non-trivial claim in the answer cites a retrieved source." + type: llm-judge + goal: "Zero unsupported claims" + scenarios: + - id: grounded-question + description: "A question the internal docs can answer." + expectedBehavior: "Retrieves sources and returns a cited answer." + - id: no-supporting-source + description: "A question no retrieved source supports." + expectedBehavior: "Returns an honest no-evidence response instead of guessing." + edgeCase: true + datasets: [] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/agentspec-0.3-field-catalog.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/agentspec-0.3-field-catalog.md new file mode 100644 index 00000000..d65ae183 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/agentspec-0.3-field-catalog.md @@ -0,0 +1,136 @@ +# AgentSpec 0.3.0 — normative field catalog + +> The human-readable normative catalog for the closed 0.3.0 resource envelope. The **machine** form +> is `scripts/contract/agentspec.schema.ts` (structural) + `scripts/validate/semantic-validator.ts` +> (semantic); this file is the field-by-field reference and the record of implementation resolutions. +> 0.3.0 is the **first canonical versioned baseline** (N01/F01) — there is no 0.2 migration or history. + +## The envelope + +``` +apiVersion: agentspec.mutagent.io/v0.3.0 # D12/F01 — frozen compatibility contract; fail loudly on mismatch +kind: Agent | Skill | MultiAgent | Workflow # D01/D03 — inferred AFTER intent; strict discriminator +metadata: { id, name, version, description } # one coherent card identity (≠ apiVersion, ≠ package release) +spec: { … } # requirements-first, target-independent +``` + +### `status` — INTERNAL profile only (dev-internal; stripped on publish) + +The **public** card has NO lifecycle bookkeeping. A **dev-internal** superset adds an optional +top-level `status` stamp recording where the subject sits in the ADL loop (operator rulings +2026-07-22 / 2026-07-23; ledger `ORCH-07` / catalog `R7`): + +``` +status: # INTERNAL-only — validateAgentSpecInternal accepts it; + adl_stage: evaluate # the PUBLIC schema REJECTS it as an unknown field. + updated_at: 2026-07-23T12:00:00Z # ISO-8601 UTC instant (pattern-enforced) + last_verdict: "evaluate:PASS" # STAGE-QUALIFIED ":" (not a bare verdict) +``` + +- **Controlled extension, not a fork:** `AgentSpecInternalSchema` = the same `agentSpecRootProps` + + an optional `status`. One contract file; one set of building blocks. +- **Closed three-field object:** `adl_stage ∈ {spec,build,evaluate,diagnose,optimize}` · `updated_at` + ISO-8601 UTC · `last_verdict` stage-qualified. A **4th key fails**. +- **Stage-qualified `last_verdict`** (over a bare `PASS`) so the orchestrator build-index (loop + position) and check-sync-spec (freshness) read WHICH stage produced the verdict without a 2nd lookup. +- **Never ships:** `sanitizeForPublish(card)` strips `status` (returns a public-valid card + the + stripped keys — the SYNC-SOP mechanical proof); public validation rejects a status-bearing card + (negative fixture `internal-status-on-public.yaml`). + +Every object is **closed** (`additionalProperties:false`, F02) — an undeclared field is rejected. + +## spec (universal) + +| Field | Meaning | Required | Notes | +|---|---|---|---| +| `intent` | Requirements-first intent (see below) | ✅ | Precedes kind/target. | +| `context[]` | Inbound information + its read access (D16) | ✅ (may be empty) | | +| `actions[]` | Outbound side effects (D16) | ✅ (may be empty) | Kept separate from context. | +| `capabilities` | `{ code[], skills[], delegates[] }` | ✅ | Requirements before target selection. | +| `agent`\|`skill`\|`multiAgent`\|`workflow` | Exactly ONE kind-native body, matching `kind` | ✅ (the matching one) | Kind leakage → semantic fail. | +| `targets[]` | Destinations + generated-artifact contract | ✅ (may be empty, F05 draft) | | +| `evaluation` | `{ criteria[], scenarios[], datasets[] }` | ✅ (arrays may be empty, F05) | Universal closure. | +| `decisionsRef` | `./agentspec.decisions.md` — one colocated sidecar | optional | N03; relative sibling only. | + +### spec.intent + +`problem` (string) · `outcomes[]` · `sop[]` (long-form, **before** jobs) · `jobs[]` · `constraints[]` · +`nonGoals[]` · `assumptions[]` · `unknowns[]`. All keys required (arrays may be empty). `sop[]` entry = +`{ id, when, description, onFailure? }`; `jobs[]` entry = `{ id, description, expectedOutput }`. +`unknowns[]` forces the Builder to stop-or-ask rather than guess. + +### spec.context[] / spec.actions[] + +- **context**: `{ id, description, modalities[], source, freshness?, sensitivity?, access }` where + `access = { kind, ref, allowedOperations[], authRef? }` — read access nested with the information (D16). +- **actions**: `{ id, description, binding{kind,ref,authRef?}, allowedOperations[], approval{policy,when}, + evidence, onFailure }` — every outbound effect is bounded, gated, auditable, and safe on failure (D16). + +`kind` on `access`/`binding` is a **CLOSED binding vocabulary** — `cli · saas · mcp · sdk · host-tool` +(operator ruling R3, 2026-07-22); an unlisted kind FAILS validation (fail-loud, F02). Future kinds +arrive via a 0.3.x minor bump. + +### spec.targets[] (D08/D14/D15/N04) + +`{ id, type: harness|framework|platform|custom, name, artifact{format: markdown|code|platform-config, path}, +implementation?{language, toolchain}, capabilityFit, documentation[]{purpose, url} }`. +`artifact.format` **supersedes the prior `medium`** (FU-69). `implementation.*` is **code-only** (N04). + +### spec.evaluation (D18/D19) + +- `criteria[]` = `{ id, description, type: llm-judge|code-check, goal }` — binary, actionable. +- `scenarios[]` = `{ id, description, expectedBehavior, edgeCase? }`. +- `datasets[]` = `{ id, description, mapsTo{jobs?,scenarios?,criteria?}, categories[], caseDimensions?, + items[]|itemsRef? }`. Categories are **dataset-local** (D18); `caseDimensions` model independent + variation axes; `items[]` carry **kind-specific** `input`/`expected` payloads (opaque data). + +## Kind bodies + +- **agent**: `{ persona{role,description}, systemPrompt (sacred, verbatim), operatingType: + conversational|automation|orchestrator, triggers[]?, workflow?{inline|ref} }`. +- **skill**: `{ purpose, invocation, instructions, inputs[], outputs[], resources[], hostRequirements[], + failureBehavior, progressiveDisclosure, subagents[]? }` — host-loadable capability, **not** an Agent. +- **multiAgent**: `{ orchestrator, members[], relations{subagents{}, observes{}}, workflow{inline|ref} }`. + Members are embedded cards (or `{specRef}`) reusing parent intent/context/actions by reference + (`intentRef`/`contextRefs`/`actionRefs`); the dispatch graph must be **acyclic** (N02). +- **workflow**: `{ state, entry, nodes[] }` — the canonical graph, one dialect for standalone AND + embedded use. Node = `{ id, description, executor?{kind, ref}, contextRefs?[], edges?[]{to, + condition?, loop?{maxIterations?, exitWhen?}}, terminal? }`. The executor is the STRICT typed + `{kind, ref}` (F03/R4; `kind ∈ {member|agent|skill|action|integration|code}`); required-input + context reads live in the SEPARATE `contextRefs` node field, not in the executor. Any **returning + edge** (a DFS back edge) must declare a loop bound — unbounded loops fail (N02). + +## Semantic exit checks (`semantic-validator.ts`) + +1. **Kind leakage** — exactly the body matching `kind`; no other kind's body. +2. **Workflow graphs** — entry resolves · edge targets resolve · terminal/edge consistency · + reachability · **bounded loops** · strict `executor {kind, ref}` resolves (kind `action`→actions, + `member`→members) · the separate node `contextRefs` resolves to `spec.context` (R4). +3. **Multi-agent** — orchestrator resolves · unique member ids · relations resolve · **acyclic** + dispatch graph · member `contextRefs`/`actionRefs`/`intentRef` resolve. +4. **Targets** — `implementation.*` only on `code` artifacts (N04). +5. **Decision sidecar** — `decisionsRef` is a colocated relative sibling `./name.md` (N03); the + FS-aware half (file must exist) runs in `validateSpecFile`. +6. **Evaluation refs** — dataset `mapsTo`/`items` resolve to jobs/scenarios/criteria/categories/dimensions. + +Valid fixtures: `assets/examples/{agent,skill,multiagent,workflow}-*/agentspec.yaml`. +Invalid fixtures (one violation each): `assets/fixtures/invalid/*.yaml`. + +## Implementation resolutions (examples vs catalog divergences) + +The PRD's four commented examples are the **locked architecture** (the concrete artifacts the DoD +requires to validate); the catalog table occasionally used a different label. Where they diverged, the +schema follows the **examples**, without reopening any LOCKED F/N/D ruling. Recorded here for review: + +| # | Divergence | Resolution | Why | +|---|---|---|---| +| R1 | catalog `intent.goals[]` vs examples `outcomes[]` | `outcomes[]` | All four examples + the DoD language use `outcomes`; internally consistent. | +| R2 | catalog `members[].inline` wrapper vs examples embedding member cards directly under `members[]` | `members[]` holds an embedded card **or** `{specRef}` (no `inline:` wrapper) | Matches the concrete MultiAgent example. | +| R3 | binding `kind` "cli\|saas\|mcp" (issue prose) vs examples using `sdk`/`host-tool` too | **CLOSED enum `{cli\|saas\|mcp\|sdk\|host-tool}`; unlisted kinds FAIL** | **Operator ruling 2026-07-22** (decision brief w/ previews): fail-loud, consistent with F02's closed core; future kinds via 0.3.x minor bumps. *(Superseded the provisional open-string.)* | +| R4 | executor shape `{kind,ref}` (F03) vs examples `{actionRef}`/`{memberRef}`/`{contextRefs}` | **STRICT `executor: {kind, ref}`; `contextRefs` is a SEPARATE node field; provisional forms REMOVED** | **Operator ruling 2026-07-22**: F03's locked text wins over the PRD's internally-divergent examples; examples/fixtures rewritten; a negative fixture proves the removed forms fail. `executor.kind ∈ {member\|agent\|skill\|action\|integration\|code}`. *(Superseded the provisional all-optional shape.)* | +| R5 | "returning edge" bound (N02) — which edge in a cycle must carry the bound | the **DFS back edge** only, not the forward edges of the cycle | A reachability test wrongly flags forward edges; back-edge detection matches the example's single `loop:` edge. | +| R6 | `capabilities.skills`/`delegates` shown only empty in examples | `skills[]` and `delegates[]` = arrays of string ids | Lean; the only populated case (`delegates`) is member ids. | +| R7 | freshness/loop-state tracking — none in the public 0.2 contract ("the spec IS the subject record") | **INTERNAL-only top-level `status: {adl_stage, updated_at, last_verdict}`** — a controlled extension (`AgentSpecInternalSchema` superset, same file), **closed** (4th key fails), stripped on publish | **Operator rulings 2026-07-22 / 2026-07-23** (freshness HELD through rejected A/B/C designs, then re-scoped to an internal `status:` block + GO). Public schema REJECTS it (negative fixture `internal-status-on-public.yaml`); `sanitizeForPublish` strips it (mechanical proof). `last_verdict` is **stage-qualified** ("evaluate:PASS"). Supersedes 0.2 "no external registry" for internal loop tracking only. See ledger `ORCH-07`. | + +Anything the Observer/operator judges wrong here is a fixable implementation detail, not a reopened +design ruling. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/frameworks/doc-pins.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/frameworks/doc-pins.md new file mode 100644 index 00000000..c4afe60b --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/frameworks/doc-pins.md @@ -0,0 +1,53 @@ +# Framework Doc Pins + +> **PR-002 — fetched at build, never copied.** These are the CANONICAL documentation ROOTS the +> `*build` agent (`ai-engineer`) crawls FRESH (WebFetch) at build time for the chosen +> `build.target_framework`. SDKs churn — never vendor the doc BODIES into this skill. PIN the roots +> here (and per-spec in `appendix.framework_docs`); crawl them live when building. + +## Pinned roots (per target) + +| Target | `llms.txt` / index root | Reference root | Notes | +|---|---|---|---| +| `mastra` | `https://mastra.ai/llms.txt` | `https://mastra.ai/reference/agents/agent` | TS-native agent framework. | +| `deepagents` | `https://reference.langchain.com/python/deepagents/` | `github.com/langchain-ai/deepagents` | LangChain deep-agents. | +| `pydantic-ai` | `https://ai.pydantic.dev/llms-full.txt` | `https://ai.pydantic.dev/api/agent/` | `llms.txt` intermittently drops the Agent section → use the HTML `api/agent/` fallback. | +| `langgraph` | `https://docs.langchain.com/llms.txt` | `https://docs.langchain.com/oss/python/langgraph/graph-api` | Docs moved to `docs.langchain.com`; only fully-declarative graph target. | + +## Provider best-practices (dogfood F3 — crawl + apply at build) + +The `*build` agent also crawls the chosen MODEL PROVIDER's best-practice docs and applies them to the +scaffold — chiefly **prompt-caching** (cache the static `system_prompt` + tool/skill defs + few-shot +prefixes). Pin the provider's caching root for whichever provider the spec's models target; crawl it +FRESH (PR-002) — never guess the caching API. + +| Provider | Prompt/context caching root | Notes | +|---|---|---| +| Anthropic | `https://docs.claude.com/en/docs/build-with-claude/prompt-caching` | `cache_control` breakpoints; cache the long static prefix. | +| OpenAI | `https://platform.openai.com/docs/guides/prompt-caching` | Automatic for long prompts; order static content first. | +| Google (Gemini) | `https://ai.google.dev/gemini-api/docs/caching` | Explicit context caching for repeated large prefixes. | + +The `ai-architect` Verifier confirms the caching (and any other crawled best-practice) was +actually applied to the scaffold — a skipped, documented best-practice is a STEER. + +## Harness targets + +`build.target_framework` may also be a HARNESS of the form `harness:` (PR-005), e.g. +`harness:claude-code` or `harness:codex`. Harness targets emit a skill/agent definition for the +named coding-agent runtime rather than a framework SDK scaffold. Harness-target doc pins + the +emission shape are a Wave-2 `*build` concern (careful-design item) — they are NOT enumerated here +yet, by design (lean, PR-007). + +## How a pin is used (PR-002) + +1. The spec's `appendix.framework_docs[target]` carries the spec-specific pin list (it may add to or + override the canonical roots above). +2. At `*build`, `ai-engineer` runs `*crawl-docs` → WebFetch each pinned root FRESH. +3. If a pin is dead/moved, the Actor escalates rather than scaffolding against a stale local copy. +4. The `ai-architect` Verifier confirms every framework API the scaffold uses appears in the + crawled docs; an unpinned/guessed API is a STEER. + +## Maintenance + +When an upstream framework moves its docs, update the pinned root HERE (and note the move). Do NOT +add a vendored copy of the doc body — the whole point of pinning is to crawl fresh. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/principles.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/principles.md new file mode 100644 index 00000000..fb72dd08 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/principles.md @@ -0,0 +1,96 @@ +# Design Principles — mutagent-agentspec + +> Operator-locked rule set. Every change to `mutagent-agentspec` is judged against these. +> 🔒 = operator-LOCKED. Each entry: **Rule** (the law) · `Applies:` (the surfaces it governs) · +> **Audit** (the yes/no question a reviewer asks). PR-001..PR-019 were authored from the design +> session captured in `mutagent-system/.memory/features/mutagent-agentspec/PRD.md`. PR-020..PR-023 +> were added from the **lab-overseer dogfood** (2026-06; the schema 0.1.0→0.2.0 migration); PR-024 from +> the build-faithfulness **sim F-gap** (2026-06); PR-025 from the **helix-dogfood remediation** (SPEC-1, +> 2026-07 — operator-directed). Append new principles to this file as waves land — this surface expands +> over time. +> +> The skill IS the **ADL ① SPEC** stage: a guided interview that captures *what an agent IS* +> (the Definition / interface) and emits a portable, validated `agentspec.yaml`. A later `*build` +> implements it into a target (the implementation). The spec is the single source of truth; the +> implementation cascades one direction (def → impl). + +--- + +#### PR-001 — Definition / Implementation separation 🔒 +**Rule:** The `agentspec.yaml` is the **Definition** (the interface — WHAT the agent is, framework-independent). It is the single source of truth. Implementations cascade ONE direction (def → impl): editing the spec and re-running `*build` updates the implementation; the implementation never silently mutates the spec (the only backwards path is the explicit, audited auto-spec-correction in `*optimize`, a later wave). Applies: scripts/contract/agentspec.schema.ts (definition vs build vs appendix split), references/workflows/orchestrator-protocol.md. **Audit:** is the spec the SSoT, with impl cascading one-way def→impl? + +#### PR-002 — Framework docs fetched-at-build, never copied 🔒 +**Rule:** `*build` crawls the pinned framework documentation FRESH (WebFetch) at build time from the roots listed in `references/frameworks/doc-pins.md` + the spec's `appendix.framework_docs`. SDKs churn; a stale local copy of a framework's API would scaffold against an outdated surface. PIN the doc ROOTS; never vendor the doc BODIES into the skill. Applies: references/frameworks/doc-pins.md, mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md, agentspec.schema.ts (appendix.framework_docs). **Audit:** does the build crawl pinned docs fresh rather than read a vendored copy? + +#### PR-003 — Model intent is sacred 🔒 +**Rule:** A `model` named in the spec (or a `subagents[].model`) is honored verbatim — no silent swap, no context-optimized routing, no retry-on-failure alternate-model fallback. `thinkingBudget`-style inference intent is operative, not cosmetic. If a target cannot satisfy a model constraint, THROW — never silently re-target. Applies: agentspec.schema.ts (tools.subagents[].model), assets/agents/*.md (inference pin blocks). **Audit:** is every declared model honored verbatim, with a THROW (not a swap) when unsatisfiable? + +#### PR-004 — Target-conditional tool binding (revised — was "MCP-first") 🔒 *(dogfood-directed revision)* +**Rule:** The tool-binding preference is resolved **AFTER the framework is known** (`build.target_framework`, asked early per F3), not as a blanket MCP-first rule. Bias the binding to the chosen target's ecosystem: +- **harness targets** (`harness:claude-code` / `harness:codex`) → **CLI-first**: prefer the harness's native CLI tools (`gh` / `git` / framework `cli`) — these runtimes bind CLIs directly and idiomatically. +- **code-frameworks** (langgraph / mastra / pydantic-ai / deepagents) → **MCP / Composio / SDK-first**: prefer an MCP `ref` (the converging portable tool layer), a Composio binding, or the framework's native SDK integration. + +`tools.integration[].kind` still spans `cli|saas|mcp`; the interview picks the binding the chosen target favors rather than always reaching for MCP. **Revision note:** PR-004 was originally "blanket MCP-first" and is operator-LOCKED; the operator DIRECTED this change (ADL ① SPEC dogfood F5) — a blanket MCP-first rule mis-bound harness/CLI agents. The minimal, audited revision replaces the blanket rule with a target-conditional preference; no other locked principle is touched. Applies: agentspec.schema.ts (tools.integration), references/workflows/orchestrator-protocol.md (D4 tools interview step). **Audit:** does the interview resolve the tool-binding preference from the chosen target (CLI-first for harnesses, MCP/Composio/SDK for code-frameworks), rather than blanket MCP-first? + +#### PR-005 — The target may be a harness 🔒 +**Rule:** `build.target_framework` accepts framework targets (mastra · deepagents · pydantic-ai · langgraph) AND HARNESS targets of the form `harness:claude-code` / `harness:codex` / `harness:`. It is therefore typed as a String (with a documented example set), not a closed Union, so harness:* and future targets are expressible without a schema bump. Applies: agentspec.schema.ts (build.target_framework). **Audit:** can `build.target_framework` express a `harness:*` value and a not-yet-enumerated framework? + +#### PR-006 — AskUserQuestion is a parent-only interview 🔒 +**Rule:** The `*spec` interview runs on the PARENT session (AskUserQuestion on Claude Code; chat-fallback multi-choice elsewhere). Sub-agents cannot ask the operator questions, so the interview is never delegated to one. The parent session IS the domain orchestrator. Applies: references/workflows/orchestrator-protocol.md (FSM), SKILL.md §0. **Audit:** does the interview run on the parent session, never inside a dispatched sub-agent? + +#### PR-007 — Lean by design (ship `*spec` before `*build`) 🔒 +**Rule:** Ship the SPEC stage fully before the BUILD stage. `*spec` + `*validate-spec` are complete this wave; `*build` + `*eval` are OUTLINED (protocol prose + the two shipped agent contracts) and wired in a later wave. Do not pad the build loop before the spec is solid. Applies: SKILL.md §0.1, references/workflows/orchestrator-protocol.md (`*build`/`*eval` outline sections). **Audit:** is `*spec` fully shipped while `*build`/`*eval` remain outlined-only? + +#### PR-008 — All dispatched sub-agents are skill-shipped 🔒 +**Rule:** `mutagent-agentspec` dispatches ONLY its OWN sub-agent contracts, shipped in `assets/agents/*.md` and carried in the npm tarball. There is NO dependency on a host/monorepo `architect`, `developer`, `general-purpose`, or `llm-whisperer` agent — those may not exist in a standalone `pnpx @mutagent/agentspec init` environment. Applies: mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md, mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md, references/workflows/orchestrator-protocol.md. **Audit:** does every dispatched agent resolve to a shipped `assets/agents/*.md`, with zero host-agent references? + +#### PR-009 — Explicit-intent transitions (no auto-advance) 🔒 +**Rule:** The ADL loop never auto-advances. Helix (the orchestrator) KNOWS the next stage and proactively SUGGESTS it + renders loop position, but every transition (spec→build, build→eval, …) requires explicit operator confirmation. "Auto-orchestrate" means suggest, never auto-run. Applies: references/workflows/orchestrator-protocol.md, meta.loop_state in agentspec.schema.ts. **Audit:** does a stage transition require explicit operator intent rather than firing automatically? + +#### PR-010 — Loop-state lives inside the spec 🔒 +**Rule:** `meta.loop_state` (`stage`, `last_verdict?`, `updated_at`) lives INSIDE `agentspec.yaml` — the spec IS the subject record. There is no separate registry; a planned (not-yet-built) agent is a first-class trackable subject from spec-time. Helix reads `meta.loop_state.stage` for loop position. Applies: agentspec.schema.ts (meta.loop_state), references/workflows/orchestrator-protocol.md. **Audit:** is loop position read from `meta.loop_state` in the spec, with no external registry? + +#### PR-011 — Spec ↔ impl ↔ eval sync triad 🔒 +**Rule:** When a spec exists, the Definition, the built implementation, and the eval suite stay in lockstep. An IMPL defect → patch code AND auto-correct the spec (backwards impl→spec patch is a first-class, audited path); a DEFINITION gap → re-spec → `*build`. (Standalone diagnostics with NO spec just patches impl — the triad only applies when a spec exists.) This is OUTLINED this wave; the mechanism lands with `*build`/`*optimize`. Applies: references/workflows/orchestrator-protocol.md (`*build`/`*eval` outlines), PRD §H.3. **Audit:** is the triad's auto-spec-correction described as the closure mechanism (not yet built, but specified)? + +#### PR-012 — 1-spec ↔ N-versioned-subjects identity anchor 🔒 +**Rule:** `meta.spec_id` is the canonical agent identity that survives every version. One active AgentSpec can have N versioned subjects (built impls / evaluator SubjectProfiles / diagnostics EntityContexts); they resolve to the spec by `spec_id` and reconcile against it. Applies: agentspec.schema.ts (meta.spec_id, meta.spec_version), references/principles.md PR-013. **Audit:** is `meta.spec_id` a stable identity anchor independent of version? + +#### PR-013 — Backwards-only linking 🔒 +**Rule:** The link points BACKWARDS: subjects → spec. The spec is implementation-AGNOSTIC — it does NOT enumerate its impls/subjects. Each downstream artifact (built impl · SubjectProfile · EntityContext) carries `spec_id` and points UP. The schema therefore has NO downstream `links`/`subjects` field by construction. Applies: agentspec.schema.ts (meta has spec_id but no downstream links), scripts/contract/agentspec.schema.test.ts (closed-object rejects a `links` field). **Audit:** does the spec carry NO downstream enumeration of its subjects/impls? + +#### PR-014 — System-prompt + persona are first-class spec fields 🔒 +**Rule:** `definition.system_prompt` is the ACTUAL operative system prompt the runtime sends (the full text, not a summary), and `definition.persona` (role + verbose persona) is a first-class operative field. They are required, not optional commentary. Applies: agentspec.schema.ts (definition.system_prompt: String required; definition.persona), assets/templates/agentspec.yaml.tpl (a real multi-paragraph prompt). **Audit:** are `system_prompt` + `persona` required, primary operative fields (not summaries)? + +#### PR-015 — Verbose descriptions everywhere 🔒 +**Rule:** Every tool, context source, job, sub-agent, skill, and trigger in the spec carries a VERBOSE `description` — it is the primary field the implementing LLM reads to understand intent. A terse/empty description defeats the spec. The worked template models verbose descriptions on every entry. Applies: agentspec.schema.ts (description: String on tools/context_sources/jobs/subagents/skills/triggers), assets/templates/agentspec.yaml.tpl. **Audit:** does every tool/source/job/subagent/skill/trigger carry a verbose description? + +#### PR-016 — Standardized SOP block 🔒 +**Rule:** `definition.sop[]` is a STANDARDIZED operating-procedure block: each entry = `when` (trigger condition) + `context` (what is loaded/required) + `procedure` (the verbose step-by-step) + optional `on_outcome.{success,failure}`. This is how the agent OPERATES, by condition + context — distinct from `modeling` (the decision graph). Applies: agentspec.schema.ts (definition.sop), assets/templates/agentspec.yaml.tpl. **Audit:** does each SOP entry carry when + context + procedure? + +#### PR-017 — Agent activation triggers are first-class 🔒 +**Rule:** `definition.triggers[]` describes how the DESIGNED agent is ACTIVATED — its inbound event sources (a2a · webhook · schedule · queue · event · mcp · manual). This is a first-class spec field and is DISTINCT from the in-system `*monitor` agent (which re-enters the ADL loop on a SYSTEM event). The designed agent's own inbound events live here, never in `*monitor`. Applies: agentspec.schema.ts (definition.triggers), references/workflows/orchestrator-protocol.md (triggers interview step), PRD §H connection-point CP9. **Audit:** are the designed agent's inbound activation events captured in `definition.triggers`, distinct from `*monitor`? + +#### PR-018 — Standalone + symbiosis (zero sibling-skill source refs) 🔒 +**Rule:** Every shipped artifact under `.claude/skills/mutagent-agentspec/` is a sealed unit with ZERO source reference to any sibling skill — and in particular NONE to the internal skill-construction skill (internal, not for release; the verifier greps for its registry name and expects empty). The `*eval` handoff to an evaluator is a designed FEATURE mentioned at the doc/protocol level only; it is never a code import. Applies: ALL of `.claude/skills/mutagent-agentspec/**`. **Audit:** does the sibling-skill registry-name grep over the skill tree return empty, and are there zero cross-skill code imports? + +#### PR-019 — Eval criteria are append-extensible 🔒 +**Rule:** `definition.evals.success_criteria[]` is binary-actionable AND append-extensible across loop iterations. You cannot pre-know every criterion at spec-time; diagnose/discover findings ADD criteria back into the spec, which re-seed the eval suite. The schema therefore models success_criteria as an open, growable array (never a fixed-length tuple). Applies: agentspec.schema.ts (definition.evals.success_criteria: Array), references/workflows/orchestrator-protocol.md (`*eval` outline). **Audit:** can `success_criteria` grow across iterations (modeled as an extensible array)? + +#### PR-020 — Scenarios are a first-class eval field 🔒 *(dogfood F1)* +**Rule:** `definition.evals.scenarios[]` captures the SITUATIONS the agent must handle — each `{id, description (the situation), expected_behavior, category?, edge_case?}`. The interview probes explicitly for the HARD / adversarial edge-cases a naive spec forgets; scenarios are the seed material an evaluator turns into eval items. Required key (schema 0.2.0). Origin: lab-overseer's emitted spec carried zero scenarios. Applies: agentspec.schema.ts (ScenarioSchema, definition.evals.scenarios), references/workflows/orchestrator-protocol.md (interview D10), assets/templates/agentspec.yaml.tpl. **Audit:** does the spec enumerate the situations the agent handles, including edge-cases? + +#### PR-021 — Dataset categories define the golden eval-suite 🔒 *(dogfood F2)* +**Rule:** `definition.evals.dataset_categories[]` is the dataset DEFINITION the `*eval` stage consumes — each `{id, description (the use-case slice), edge_cases[]}`. The spec SEEDs the evaluator's dataset (seed, don't duplicate — PR-018); it is the by-use-case + edge-case coverage map the golden suite is built from. Required key (0.2.0). Origin: lab-overseer's spec had no dataset definition, so `*eval` had nothing to build from. Applies: agentspec.schema.ts (DatasetCategorySchema, definition.evals.dataset_categories), references/workflows/orchestrator-protocol.md (interview D11). **Audit:** does the spec define the golden eval-suite slices + edge-cases the dataset must cover? + +#### PR-022 — Runtime is pinned at spec-time 🔒 *(dogfood F4)* +**Rule:** `build.runtime` (bun · node · deno · python · shell · …) is PINNED at spec-time so `*build` implements ONCE — never pick-a-runtime-then-rebuild. Required key (0.2.0). The Actor builds for that runtime only; the Verifier flags a runtime-rebuild as STEER. Origin: lab-overseer was built in bash then rebuilt in Bun because the runtime was never specified. Applies: agentspec.schema.ts (build.runtime), references/workflows/orchestrator-protocol.md (interview B1), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md (Step 2), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md (pre-flight). **Audit:** is the implementation runtime fixed in the spec before `*build` runs? + +#### PR-023 — Build applies provider best-practices, crawled fresh 🔒 *(dogfood F3)* +**Rule:** `*build` applies the model provider's best-practices — chiefly PROMPT-CACHING (static `system_prompt` + tool/skill defs + few-shot in cache-eligible prefixes) — read FRESH from the provider's caching docs (pinned in `references/frameworks/doc-pins.md`), never guessed. Extends PR-002 (fetched-at-build) from framework docs to PROVIDER docs. The Verifier confirms caching was applied; a skipped documented best-practice is a STEER. Origin: lab-overseer's build applied no caching / provider hygiene. Applies: references/frameworks/doc-pins.md (provider caching roots), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md (Step 2.5), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md (pre-flight). **Audit:** does the build crawl + apply provider prompt-caching, verified by the architect? + +#### PR-024 — Build-faithfulness gate: TDD-green is not enough 🔒 *(dogfood — sim F-gap)* +**Rule:** A `*build` is GREEN only when the TDD loop passes AND a deterministic **spec→impl coverage gate** passes. TDD proves the code that EXISTS is correct; it is SILENT on whether all the code the spec REQUIRES exists (a dropped tool has no test to fail). Every `definition.tools.code[].id` MUST map to an implementing module carrying `// @implements ` AND a referencing test; any `jobs_to_be_done[].backed_by` ref MUST resolve to a declared code tool. The Actor runs the gate as Step 3.5; the Verifier RE-RUNS it independently (Context-Inversion — faithfulness is scripted, never prose-judged). A miss is a STEER naming the tool. Origin: the dogfood sim shipped a scaffold missing the `collect-range` tool with 27 green tests — a green TDD loop did not catch a dropped spec tool. Applies: mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts (+test), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md (Step 3.5 + termination), mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md (scripted pre-flight), references/workflows/orchestrator-protocol.md (`*build` two-gate green), scripts/contract/agentspec.schema.ts (jobs_to_be_done[].backed_by?). **Audit:** is every spec-declared code tool asserted (by a deterministic gate the Verifier re-runs) to have an `@implements` module + a test before a build is green? + +#### PR-025 — Enumerate the real surface before assuming; template-driven extraction + LLM cross-verify 🔒 *(helix-dogfood SPEC-1)* +**Rule:** A reverse-generated spec (`*sync-spec` cold CONSTRUCT / warm RECONCILE) is NEVER free-read in one pass. Before reading the implementation's own prose, the single implementation-reader (builder's `ai-architect #sync-spec`) ENUMERATES the real surface — every actual CLI command / entrypoint / handler, hook, file, tool/MCP/integration registration, context source, sub-agent, inbound trigger, and env/config — into an explicit checklist, then drives extraction off the agentspec TEMPLATE slot skeleton (`assets/templates/agentspec.yaml.tpl`, derived deterministically by `scripts/template/slot-checklist.ts`) so EVERY slot is deliberately FILLED or marked N/A — never resolved silently. It THEN runs an LLM CROSS-VERIFY of the drafted spec back against the enumerated surface (the **impl→spec** direction, which `spec-impl-coverage.ts` — spec→impl only, at BUILD — has no home for) and reports every surface item present but missing/partial in the draft; AgentSpec surfaces those omissions to the operator UP FRONT. Tied to the agentspec (enumerated surface + template slots), NOT a mechanical tools↔jobs diff — `*validate-spec` checks field SHAPES only, so completeness cannot come from the schema gate. Origin: the ADL ① SPEC dogfood — the derive captured only a fraction of the command/hook surface silently and showed no work; the operator directed "explore and understand the real surface before assuming" as a core principle. Applies: mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md (#sync-spec enumerate-first + cross-verify), references/workflows/orchestrator-protocol.md (*sync-spec flow), scripts/template/slot-checklist.ts (+test), assets/templates/agentspec.yaml.tpl. **Audit:** does `*sync-spec` enumerate the real surface into a template-slot checklist (every slot filled or N/A) and LLM-cross-verify the draft against it (impl→spec, reporting surface-present/spec-absent items) before assuming? diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/requirements.yaml b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/requirements.yaml new file mode 100644 index 00000000..10f2c7d0 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/requirements.yaml @@ -0,0 +1,305 @@ +# Requirements registry — mutagent-agentspec +# +# Machine-readable requirements hub. Ships with the skill (a sibling of principles.md). +# Requirements are the HUB: +# OUTBOUND — `features` (the wave work that implements the REQ; empty ⇒ UNMET), +# `evalCriteria` (what audits it; empty ⇒ UN-AUDITED — an honest gap), +# `principles` (the design rule it honors — PR-NNN in references/principles.md). +# INBOUND — `feedbackSources` (the operator design note that motivated it). +# +# Source-of-truth chain: this file (HUB) → principles.md GOVERNS → the in-repo PRD is the +# narrative. NDA: no client identity, synthetic only. + +meta: + subject: mutagent-agentspec + version: "0.1.0-alpha.0" + description: > + Product requirements for the ADL ① SPEC skill — the guided requirements interview that + emits a portable, validated agentspec.yaml. Derived from the operator design session, the + SKILL.md surface, principles.md (PR-001..PR-019), and the agentspec.v0.2.0 contract. + path: mutagent-system/mutagent-agentspec/.claude/skills/mutagent-agentspec/references/requirements.yaml + generatedFrom: + - "mutagent-system/.memory/features/mutagent-agentspec/PRD.md (the in-repo design source of truth)" + - "references/principles.md (PR-001..PR-019)" + - "references/workflows/orchestrator-protocol.md (the *spec interview FSM)" + - "scripts/contract/agentspec.schema.ts (the agentspec.v0.2.0 contract)" + feedbackSources: + - "operator design session 2026-06 — mutagent-agentspec plan (PRD.md)" + +requirements: + # ───────────────────────── DEFINITION — persona + prompt ───────────────────────── + - id: REQ-001 + title: Capture persona (role + verbose persona) and the actual system prompt as first-class fields + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.persona required", "schema:definition.system_prompt required-string", "template: real multi-paragraph system_prompt validates"] + principles: [PR-014, PR-015] + feedbackSources: ["PRD §B: persona + system_prompt are primary operative text, not a summary"] + + - id: REQ-002 + title: Capture jobs-to-be-done with verbose what+why and expected output + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.jobs_to_be_done[] {id,description,expected_output}"] + principles: [PR-015] + feedbackSources: ["PRD §B: jobs_to_be_done = the 'Requirements' (CrewAI-task-aligned)"] + + # ───────────────────────── DEFINITION — context + tools ───────────────────────── + - id: REQ-003 + title: Capture context sources (kind + where_from + verbose description + optional auth_ref) + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.context_sources[] kind∈{api,saas,internal-service,mcp,cli}"] + principles: [PR-015] + feedbackSources: ["PRD §B: context_sources = what context + where it comes from"] + + - id: REQ-004 + title: Capture tools across four buckets (integration / code / skills / subagents), each with a verbose description + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.tools.{integration,code,skills,subagents}", "schema:every tool entry carries a description"] + principles: [PR-004, PR-015] + feedbackSources: ["PRD §B: tools nested formal fields, ALWAYS a verbose description; MCP-first binding"] + + # ───────────────────────── DEFINITION — type / triggers / modeling / sop / evals ───────── + - id: REQ-005 + title: Capture agent_type (conversational / automation / orchestrator) + status: done + priority: P1 + features: [wave-1] + evalCriteria: ["schema:definition.agent_type closed enum"] + principles: [PR-013] + feedbackSources: ["PRD §B: agent_type is a first-class definition field"] + + - id: REQ-006 + title: Capture activation triggers (a2a/webhook/schedule/queue/event/mcp/manual) as a first-class field distinct from *monitor + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.triggers[] kind enum", "principles: PR-017 *monitor distinction documented"] + principles: [PR-017] + feedbackSources: ["PRD §H CP9: the designed agent's inbound activation events live in definition.triggers, NOT *monitor"] + + - id: REQ-007 + title: Capture modeling (LangGraph-aligned decision_graph + workflows) + status: done + priority: P1 + features: [wave-1] + evalCriteria: ["schema:definition.modeling.decision_graph {state,nodes,edges}"] + principles: [PR-013] + feedbackSources: ["PRD §B: modeling.decision_graph LangGraph-aligned"] + + - id: REQ-008 + title: Capture a standardized SOP block (when + context + procedure + optional on_outcome) + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.sop[] {when,context,procedure}"] + principles: [PR-016] + feedbackSources: ["PRD §F principles added: standardized SOP block (condition + context + procedure)"] + + - id: REQ-009 + title: Capture binary-actionable, append-extensible eval success_criteria + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:definition.evals.success_criteria[] {id,criterion,type,goal}", "criteria modeled as growable array"] + principles: [PR-019] + feedbackSources: ["PRD §H.3: eval criteria FLEX/grow across loop iterations"] + + # ───────────────────────── BUILD ───────────────────────── + - id: REQ-010 + title: Capture build target_framework (incl. harness:*) and target_eval_framework as guided choices inside the spec + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:build.target_framework String accepts harness:* + future frameworks", "schema:build.target_eval_framework"] + principles: [PR-005, PR-001] + feedbackSources: ["PRD §B: build.target may be a HARNESS; lives inside the spec → cascade-update"] + + # ───────────────────────── META / IDENTITY / LOOP ───────────────────────── + - id: REQ-011 + title: Carry meta.spec_id identity anchor + meta.loop_state inside the spec; backwards-only linking + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["schema:meta.spec_id + meta.loop_state.stage", "schema:NO downstream links (closed object rejects a links field)"] + principles: [PR-010, PR-012, PR-013] + feedbackSources: ["PRD §H.2/H.4: loop-state-in-spec; 1-spec↔N-subjects; backwards-only linking"] + + # ───────────────────────── APPENDIX / DOC-PINNING ───────────────────────── + - id: REQ-012 + title: Pin framework doc roots in the appendix; *build crawls them fresh (never vendor doc bodies) + status: done + priority: P1 + features: [wave-1] + evalCriteria: ["schema:appendix.framework_docs Record", "references/frameworks/doc-pins.md present"] + principles: [PR-002] + feedbackSources: ["PRD §B appendix: PIN doc roots; crawl fresh at build (SDKs churn)"] + + # ───────────────────────── VALIDATION GATE ───────────────────────── + - id: REQ-013 + title: TypeBox round-trip schema gate — *validate-spec validates a spec file; the worked template asserts valid + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["scripts/validate/validate-spec.ts pure fn + CLI", "test: template agentspec.yaml.tpl validates", "test: closed-object rejects an undeclared field"] + principles: [PR-001, PR-013] + feedbackSources: ["PRD §G: the interview yields a schema-valid spec; round-trip validation"] + + # ───────────────────────── INTERVIEW (the *spec FSM) ───────────────────────── + - id: REQ-014 + title: The *spec interview runs on the parent session (AskUserQuestion / chat fallback) — no coordinator sub-agent + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["references/workflows/orchestrator-protocol.md FSM walks all definition+build areas", "SKILL.md §0: parent session is orchestrator"] + principles: [PR-006, PR-007] + feedbackSources: ["PRD §C: *spec full, parent-session-driven; AskUserQuestion can't run in a sub-agent"] + + # ───────────────────────── BUILD / EVAL (OUTLINED) ───────────────────────── + - id: REQ-015 + title: Ship two standalone *build sub-agent contracts (ai-engineer Actor + architect Verifier) with zero host-agent dependency + status: done + priority: P0 + features: [wave-1] + evalCriteria: ["mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-engineer.md present", "mutagent-builder/.claude/skills/mutagent-builder/assets/agents/ai-architect.md present", "grep: zero host architect/developer/general-purpose/llm-whisperer refs"] + principles: [PR-008] + feedbackSources: ["PRD §D: ALL dispatched sub-agents are skill-shipped; NO host-agent dependency"] + + - id: REQ-016 + title: '*build (implement spec into target + TDD) is OUTLINED only this wave' + status: outlined + priority: P1 + features: [wave-2] + evalCriteria: ["references/workflows/orchestrator-protocol.md#build outline present"] + principles: [PR-007, PR-002] + feedbackSources: ["PRD §E lean phasing: Wave-2 = *build (lightweight, careful)"] + + - id: REQ-017 + title: '*eval handoff to an evaluator is OUTLINED only (doc/protocol level, never a code import)' + status: outlined + priority: P2 + features: [wave-3] + evalCriteria: ["references/workflows/orchestrator-protocol.md#eval-handoff outline present", "grep: evaluator mention is doc-level handoff, not import"] + principles: [PR-007, PR-018] + feedbackSources: ["PRD §C/§E: *eval outlined/phased handoff to mutagent-evaluator"] + + # ───────────────────────── STANDALONE + SYMBIOSIS ───────────────────────── + - id: REQ-018 + title: Standalone — zero source reference to any sibling skill (HARD ban on the internal skill-construction skill) + status: done + priority: P0 + features: [wave-0, wave-1] + evalCriteria: ["sibling-skill registry-name grep over the skill tree returns empty", "no cross-skill code imports"] + principles: [PR-018] + feedbackSources: ["PRD §A: standalone + symbiosis (CORE); ignore the internal skill-construction skill"] + + # ───────────────────────── HELIX ROUTING ───────────────────────── + - id: REQ-019 + title: Register *spec in Helix routing additively (AdlStage.Spec + dispatch ROUTE + topology classification + routing.yaml + docs) + status: done + priority: P0 + features: [wave-0] + evalCriteria: ["dispatch.ts *spec ROUTE resolves to mutagent-agentspec/adl_stage spec/interactive/ungated", "sync-index STAGE_BY_NAME mutagent-agentspec→spec", "orchestrator dispatch.test.ts *spec case green"] + principles: [PR-009] + feedbackSources: ["PRD §H CP2: add *spec + AdlStage.Spec to dispatch.ts/routing.yaml"] + + # ───────────────────────── PACKAGE DISCIPLINE ───────────────────────── + - id: REQ-020 + title: Self-host the skill's own PRD under .memory/features/; never ship it in the npm tarball + status: done + priority: P1 + features: [wave-0, wave-1] + evalCriteria: [".memory/features/mutagent-agentspec/PRD.md present", "npm pack --dry-run excludes .memory/ + .meta/ + *.test.ts", ".meta/design-principles.md + requirements.yaml meta point at the PRD"] + principles: [PR-001, PR-018] + feedbackSources: ["operator condition 2026-06: the Spec module maintains its own Spec (self-hosted PRD, stripped at publish)"] + + # ─────────────── DOGFOOD F1–F4 (lab-overseer run, 2026-06; schema 0.1.0→0.2.0) ─────────────── + - id: REQ-021 + title: Capture the SCENARIOS the agent must handle (situation + expected_behavior + edge_case flag) + status: done + priority: P0 + features: [dogfood-fix] + evalCriteria: ["schema:definition.evals.scenarios[] {id,description,expected_behavior,category?,edge_case?} required", "interview D10 probes hard/adversarial cases", "worked template carries edge-case scenarios"] + principles: [PR-019, PR-015] + feedbackSources: ["dogfood F1 (lab-overseer): the emitted spec had 0 scenarios — the spec must carry the situations the agent handles"] + + - id: REQ-022 + title: Capture the GOLDEN eval-suite slices (dataset_categories with explicit edge_cases) the *eval dataset must cover + status: done + priority: P0 + features: [dogfood-fix] + evalCriteria: ["schema:definition.evals.dataset_categories[] {id,description,edge_cases[]} required", "interview D11 captures slices + edge-cases", "seed-don't-duplicate handoff to evaluator (PR-018)"] + principles: [PR-019, PR-018] + feedbackSources: ["dogfood F2 (lab-overseer): no dataset definition — *eval had nothing to build a golden suite from"] + + - id: REQ-023 + title: Pin the implementation RUNTIME at spec-time so *build implements once (no pick-then-rebuild) + status: done + priority: P0 + features: [dogfood-fix] + evalCriteria: ["schema:build.runtime required String (bun|node|deno|python|shell|…)", "interview B1 recommends runtime from target", "ai-engineer Step 2 builds for build.runtime ONLY", "architect pre-flight flags a runtime-rebuild as STEER"] + principles: [PR-001] + feedbackSources: ["dogfood F4 (lab-overseer): built in bash then rebuilt in Bun because the runtime was never pinned"] + + - id: REQ-024 + title: Apply provider best-practices (prompt-caching) at build, crawled FRESH from provider docs + status: done + priority: P1 + features: [dogfood-fix] + evalCriteria: ["doc-pins.md pins provider caching roots (Anthropic/OpenAI/Google)", "ai-engineer Step 2.5 applies prompt-caching from crawled docs", "architect pre-flight verifies caching applied"] + principles: [PR-002] + feedbackSources: ["dogfood F3 (lab-overseer): build applied no prompt-caching / provider best-practices"] + + # ─────────────── BUILD-FAITHFULNESS GATE (sim F-gap, 2026-06) ─────────────── + - id: REQ-025 + title: A build is green only when TDD passes AND a deterministic spec→impl coverage gate passes + status: done + priority: P0 + features: [build-hardening] + evalCriteria: ["mutagent-builder/.claude/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts: every definition.tools.code[].id needs an @implements module + a test", "ai-engineer Step 3.5 runs *coverage; termination requires coverage PASS", "architect pre-flight RE-RUNS the gate (scripted, not prose); a miss = STEER", "mutagent-builder spec-impl-coverage.test.ts replays the collect-range miss → exit 1"] + principles: [PR-024] + feedbackSources: ["dogfood sim: scaffold shipped missing the collect-range tool with 27 green tests — a green TDD loop did not catch a dropped spec tool"] + + - id: REQ-026 + title: Spec-time backing signal — jobs_to_be_done[].backed_by names the code tools that implement each job + status: done + priority: P1 + features: [build-hardening] + evalCriteria: ["schema:definition.jobs_to_be_done[].backed_by optional string[] (additive — no version bump)", "coverage gate flags a dangling backed_by ref (not a declared code tool)", "worked template demonstrates backed_by + the // @implements convention"] + principles: [PR-024] + feedbackSources: ["dogfood sim escalation E4: surface 'covered-as-spec but only NL-backed' jobs at spec time so BUILD knows its target surface"] + + # ─────────────── SPEC-STAGE INTERVIEW UX (ADL ① SPEC dogfood, 2026-06) ─────────────── + - id: REQ-027 + title: 'BROWNFIELD/DRIFT — *sync-spec reconciles a draft agentspec against a target (delegated to ai-architect #sync-spec; subject-agnostic)' + status: done + priority: P1 + features: [spec-stage] + evalCriteria: ["SKILL.md §0.1 carries a *sync-spec command row (own entry · delegates read → ai-architect #sync-spec)", "orchestrator-protocol.md has the #sync-spec section (AgentSpec emits a HandoverBundle → Helix dispatches ai-architect #sync-spec → reads target + drafts → operator confirms inferred fields → emit + *validate-spec)", "the former *spec-from-impl + builder *spec-sync are FUSED in (grep: no *spec-from-impl / *spec-sync command rows remain)", "grep: no per-connector / Slack / GitHub-app / subject-specific logic in the reconcile path"] + principles: [PR-001, PR-006, PR-014] + feedbackSources: ["dogfood F10 (ADL ① SPEC): support adopting OR reverse-generating an agentspec FROM an existing implementation when no spec exists — generic brownfield capability only", "operator 2026-07-01: FUSE *spec-from-impl + builder *spec-sync into ONE agentspec-owned *sync-spec that delegates the code-read to ai-architect #sync-spec (reverse-generate = drift-from-nothing)"] + + - id: REQ-028 + title: 'Interview UX — infer→propose→confirm (F2), framework-before-tooling FSM order (F3), target-conditional tool binding (F5, revised PR-004), tooling matches the target language (F12)' + status: done + priority: P1 + features: [spec-stage] + evalCriteria: ["orchestrator-protocol.md D0/D5 infer→propose→confirm with the chatbot→conversational / orchestrator→a2a-router / automation→one-shot map", "FSM asks B0 (target) before D3/D4", "PR-004 revised to target-conditional binding (CLI-first harness / MCP·Composio·SDK code-framework)", "D4 biases tooling to the target's language/ecosystem (e.g. TS/Mastra → Vercel AI SDK)"] + principles: [PR-004, PR-005, PR-015] + feedbackSources: ["dogfood F2/F3/F5/F12 (ADL ① SPEC): don't cold-ask the obvious; choose the framework before the tooling; bind tools per the chosen target + its language"] + + # ─────────────── SYNC-SPEC ENUMERATE-FIRST + CROSS-VERIFY (helix-dogfood SPEC-1, 2026-07) ─────────────── + - id: REQ-029 + title: 'ENUMERATE-FIRST + LLM CROSS-VERIFY — *sync-spec reverse-generate enumerates the real surface against the template, then cross-verifies the draft (impl→spec)' + status: done + priority: P1 + features: [spec-stage] + evalCriteria: ["scripts/template/slot-checklist.ts derives the 28 Definition/Build/Appendix template slots from agentspec.yaml.tpl (+test, lockstep drift-gate)", "ai-architect.md #sync-spec carries the enumerate-first (list surface → fill-or-N/A every template slot) sub-step BEFORE free-reading prose", "ai-architect.md #sync-spec carries the LLM cross-verify sub-step (impl→spec) reporting surface-present/spec-absent items", "orchestrator-protocol *sync-spec flow derives + carries the slot checklist in the bundle AND surfaces the cross-verify omissions to the operator up front", "tied to the agentspec (template slots + enumerated surface), NOT a mechanical tools↔jobs diff"] + principles: [PR-025, PR-001, PR-014] + feedbackSources: ["helix-dogfood-remediation SPEC-1 (ADL ① SPEC): the derive captured only a fraction of the command/hook surface silently; validate-spec checks field shapes only — an incomplete spec passes as cleanly as a complete one", "operator: tie it to the agentspec — template-driven extraction + model cross-verify; always explore and understand the real surface before assuming (make it a core principle)"] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md new file mode 100644 index 00000000..1037ac95 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/references/workflows/orchestrator-protocol.md @@ -0,0 +1,396 @@ +# mutagent-agentspec — Orchestrator Protocol + +> The runtime FSM for `mutagent-agentspec`. The **parent session IS the domain orchestrator** — it +> runs the `*spec` interview itself and does **NOT** dispatch a coordinator sub-agent (PR-006). On +> Claude Code the interview uses **AskUserQuestion**; elsewhere it uses a chat-based multi-choice +> fallback. `*build` is owned by `mutagent-builder`; `*eval` is a routed handoff to EVALUATE. + +--- + +## Star-command resolution contract (verbatim) + +When you encounter a `*` token: +1. **RESERVED** — `*` marks a command. NOT prose, NOT a file path, NOT an external shortcut. + `*command` = THIS skill's semantic map (internal). Never improvise. +2. **RESOLVE** — look up `` in the `commands:` block in `SKILL.md §0.1`. Not found ⇒ ERROR + + ask the operator. NEVER guess. +3. **BINDING** — read `kind:` + `binds:`: + - `kind: script` ⇒ `binds:` a relative script path ⇒ CALL the script via `scripts/cli/run.sh`. + Do NOT re-implement it in prose. + - `kind: agent-chain` ⇒ `binds:` a workflow file#section ⇒ load + run the steps in order. + - `kind: hybrid` ⇒ `binds:` both ⇒ call script(s) for deterministic parts, reason for the rest. +4. **PRE-GATE** — load any `pre_gate.loads:`. +5. **EXECUTE** — run the steps IN ORDER. Invent nothing. +6. `purpose:` / `impact:` explain WHY (not executed). Steps MAY reference other `*commands`. + +--- + +## `*spec` — the guided interview FSM (parent session, full) + +**Goal:** walk the operator through the AgentSpec 0.3.0 resource card **intent-first**, emit the +`agentspec.yaml` (+ optional colocated `agentspec.decisions.md`), and gate it with `*validate-spec`. +The interview is parent-only (AskUserQuestion cannot run inside a sub-agent, PR-006). Every fork is an +AskUserQuestion (Claude Code) or a chat multi-choice (elsewhere) — never a bare inline prose ask, and +never a cold enum without a recommendation. Capture VERBOSE descriptions on every entry (PR-015) — the +description is the primary field the implementing LLM reads. + +The FSM walks the card **requirements-first**; state accumulates into the in-progress card; the +operator may revise an earlier answer at any point (the card is the working record). + +> **INTENT-FIRST ordering (0.3.0 — reverses the old framework-before-tooling order).** The 0.2 +> interview asked `kind` first and the target EARLY. 0.3.0 does the opposite: gather the **whole +> problem space** — problem, outcomes, long-form SOP (before derived jobs), constraints, non-goals, +> assumptions, unknowns, inbound context, outbound actions, and capability requirements — **before** +> inferring `kind`, and choose target(s) **LAST**, after the design and evaluation contract are +> complete. *A user cannot responsibly choose a kind before requirements exist, and a target must +> satisfy the final design — not prematurely constrain it.* The live order is therefore +> **I0 → I1 → I2 → I3 → I4 → I4b(capability inventory) → I5(kind) → I6(design) → I7(eval close) → +> I8(target) → I9(emit)**. +> +> **Capability inventory precedes kind (I4b before I5) — Wave-2A exit check.** The base capability +> REQUIREMENTS (code · loadable skills · **delegates**) are inventoried at **I4b, BEFORE** the kind is +> proposed, so kind is inferred FROM a complete capability picture. Capturing delegates *after* kind +> would risk circular confirmation (a `MultiAgent` guess justifying the very delegates that should +> have informed it). Kind-DRIVEN *refinement* of capabilities still happens at I6 — but the inventory +> that feeds the kind inference is fixed first. + +### Phases I0–I9 (the intent-first flow) + +| # | Phase | Captures | Schema target | +|---|---|---|---| +| I0 | **Frame problem** | domain · affected people/systems · pain · desired change · **invite source materials** — remind the operator they can point at folders/files/links (policy docs · agent-scope/role docs · existing SOPs/runbooks · a prior agent definition or prompt) to ground the interview, so they can hand over documents instead of talking everything out (see *Grounding the interview in existing materials*) | (feeds `spec.intent`) | +| I1 | **Complete intent** | `problem`; `outcomes[]`; long-form `sop[]` (id·when·description·onFailure?) **before** `jobs[]` (id·description·expectedOutput); `constraints[]`; `nonGoals[]`; `assumptions[]`; `unknowns[]` | `spec.intent` | +| I2 | **Inbound context** | per item: id · verbose description · `modalities[]` (documents/databases/email/events/human input…) · source · freshness? · sensitivity? · `access{kind,ref,allowedOperations[],authRef?}` — `kind` is the CLOSED enum `{cli\|saas\|mcp\|sdk\|host-tool}` (R3); propose the target-favored binding, never cold-ask, and never accept an unlisted kind | `spec.context[]` | +| I3 | **Outbound actions** | per effect: id · description · `binding{kind,ref,authRef?}` (same CLOSED `kind` enum, R3) · `allowedOperations[]` · `approval{policy,when}` · `evidence` · `onFailure`. Explicit **none** = `actions: []`. | `spec.actions[]` | +| I4 | **Seed evaluation** | choose **criteria-first OR dataset-first** (enforce neither, D19); draft binary-actionable `criteria[]` and/or broad `scenarios[]`; sketch dataset intent + mappings | `spec.evaluation` (draft) | +| **I4b** | **Capability inventory** *(BEFORE kind — Wave-2A exit check)* | inventory the base capability REQUIREMENTS the problem needs — local `code[]`, loadable `skills[]`, and **`delegates[]`** — as requirements, independent of any kind. This complete picture FEEDS the kind inference; never defer the delegates question past kind. | `spec.capabilities` (base) | +| I5 | **Propose kind** | INFER `Agent`\|`Skill`\|`MultiAgent`\|`Workflow` from the COMPLETE intent + the I4b capability inventory; PROPOSE with the WHY; operator confirms/corrects (see Infer→Propose→Confirm). **Never** choose kind before the I4b inventory exists. | `kind` | +| I6 | **Derive design** | the ONE kind-native body (below) + kind-driven *refinement* of capabilities (graph · triggers · host needs · expected outputs; add any capability the confirmed kind newly requires) | `spec.`, `spec.capabilities` (refined) | +| I7 | **Close evaluation** | confirm `criteria[]` · `scenarios[]` (mapped to jobs) · `datasets[]` — each dataset owns its **local** `categories[]` + `caseDimensions` and uses the kind's `input`/`expected` **item** contract (D18); every item maps to one scenario | `spec.evaluation` (final) | +| I8 | **Select target(s)** | compare capability + evaluation fit; confirm **one or many** `targets[]`: `type`(harness\|framework\|platform\|custom) · name · `artifact{format,path}` · `documentation[]` · `capabilityFit`; add `implementation{language,toolchain}` **only** for `format: code`. Record capability gaps explicitly. | `spec.targets[]` | +| I9 | **Recap + emit** | plain-language card recap (final values · consequential inferences · operator overrides · unresolved unknowns · decisions · intentionally-empty fields); on approval, emit + optional decisions sidecar + `*validate-spec` + suggest `*build` | EMIT + GATE | + +> **Four-kind interview fixtures.** The intent-first ordering is proven per kind by the transcript +> fixtures at `assets/fixtures/interview/{agent,skill,multiagent,workflow}-interview.md` — each shows +> intent preserved, unknowns exposed, integration (closed-enum binding) asked, and kind/target chosen +> only AFTER the I4b capability inventory. (A finished example *card* cannot show capture order; these do.) + +### I0 opening — the process-overview preamble (before any question) + +**Set expectations before asking anything.** The very first thing the interview does — before a +single question — is give the operator a short, plain-language overview of what's about to happen, so +they know the shape of the conversation instead of being met cold with a barrage of questions. +Deliver it once, at the top of I0, in plain words (no schema vocabulary), covering four things: **what +this does · the journey in plain words · what you get at the end · materials welcome any time.** + +> "Here's how this'll work. I'm going to interview you to build a spec for your agent — think of it as +> a shared understanding we write down and you sign off on. We'll go a step at a time, roughly in this +> order: **understand the problem** you're solving → **who it affects** → **how the work should +> happen** → **what the agent is allowed to touch and do** → **how we'll know it's working** → and +> last, **where it runs**. I'll ask in plain language and handle the technical mapping myself — it's a +> conversation, not a form, and you can revise an earlier answer at any time. At the end you get a +> reviewed `agentspec.yaml` to approve." + +Then — still at I0, and second — open the door to existing materials: the operator can hand over +documents instead of talking everything out. The overview comes **first** (what to expect); the +materials invitation comes **second** (what you can bring). The invitation itself and the read-don't- +guess discipline are defined in the next section — reference it, don't restate it here. + +### Grounding the interview in existing materials (I0 invitation · recurring reminder) + +**Docs-over-dialogue.** The operator should never have to talk out what a document they already have +states. The FSM INVITES source materials at the top and keeps the door open — the interview reads +them as context, it does not demand everything be described from scratch. + +**I0 — open with the invitation (plain language, once):** + +> "Before we talk it all out — if you already have material that describes this agent's job, point me +> at it. Folders, files, or links: policy documents, agent-scope or role documents, existing +> SOPs/runbooks, a prior agent definition or prompt. I'll read them and use them as interview context, +> so you can hand me documents instead of describing everything from scratch." + +**Recurring reminder — one line, not spam.** At each move between major phases (e.g. I1→I2, I3→I4, +I4b→I5, I6→I7, I7→I8) drop AT MOST one plain line — *"(You can hand me more material any time — a doc +beats re-typing it.)"* — never more than a single line, never on every question. + +**When materials ARE provided — read, don't guess (mirror the `*sync-spec` reading discipline):** + +| Step | Rule | +|---|---| +| **Read IN FULL** | Read every provided file/folder/link **completely** before deriving anything — evidence-first, **no filename guessing** (the same read-in-full discipline `ai-architect #sync-spec` uses, PR-025). A folder ⇒ enumerate then read its files; a link ⇒ fetch + read. | +| **Derive, don't adopt** | Project the read content onto the current phase's card fields as **INFERRED** values only — the document is evidence, never the design authority (same stance as reverse-sync: material informs, the operator still owns *why*). | +| **Infer → Propose → Confirm** | Run the existing loop OVER the extracted content: PROPOSE each document-derived field as the pre-selected default **with its source cited as the WHY**; the operator CONFIRMS or CORRECTS. A document-derived fact is **never** silently accepted as truth — it is confirmed exactly like an inferred `kind`. | +| **Cite the source** | Note the source document per derived item in the **existing** provenance language: surface it as an **inferred value (source: ``)** at propose-time and in the I9 recap's "consequential inferences" list; where the choice is consequential, the `agentspec.decisions.md` sidecar (N03) records the source as its rationale. **No new schema fields** — provenance rides the existing inferred-vs-confirmed + recap + decisions machinery. | + +Unknowns stay unknowns: a gap the documents do not answer lands in `intent.unknowns[]` — never invented +from a document's silence — exactly as on the talk-it-out path. + +### The kind-native design body (I6) — no anatomy leaks across kinds + +| kind | Body (`spec.`) captures | +|---|---| +| **Agent** | `persona{role,description}` · the ACTUAL `systemPrompt` (full sacred text, not a summary, PR-014) · `operatingType` (conversational\|automation\|orchestrator — INFER+PROPOSE) · `triggers[]?` · optional `workflow{inline\|ref}` (the ONE canonical graph contract — never a bespoke per-Agent decision graph) | +| **Skill** | `purpose` · `invocation` (host-aware activation, not inbound triggers) · `instructions` · `inputs[]` · `outputs[]` · `resources[]` · `hostRequirements[]` · `failureBehavior` · `progressiveDisclosure` · `subagents[]?` | +| **MultiAgent** | `orchestrator` (the one root member id) · `members[]` (embedded complete Agent/Skill cards, or `{specRef}` — each keeps its own intent by ref/inline; the member graph must be **acyclic**, N02) · `relations{subagents{}, observes{}}` (dispatch vs watch, kept distinct) · `workflow{inline\|ref}` | +| **Workflow** | the canonical graph directly: `state` · `entry` · `nodes[]` (id · verbose description · `executor?` {actionRef\|memberRef\|contextRefs\|kind+ref} · `edges[]`{to,condition?,loop?{maxIterations,exitWhen}} · terminal?). Any **returning edge must be bounded** (N02). | + +#### INFER → PROPOSE → CONFIRM — `kind` (I5) + Agent `operatingType` (I6) + +> **Don't cold-ask the obvious.** By I5 the operator has described the whole problem, context, actions, +> and capability needs; `kind` is usually DERIVABLE. The interview **INFERS** it, **PROPOSES** it as the +> pre-selected default with the WHY as its rationale, and lets the operator **CONFIRM or CORRECT** — +> never a bare enum. On low confidence, still propose the best guess but flag it as a guess. + +**`kind` inference map** (propose the matching value, gloss shown as rationale): + +| The complete intent sounds like… | PROPOSE `kind` | Gloss (the WHY) | +|---|---|---| +| one autonomous subject with a persona + operative prompt that decides and acts | `Agent` | a single autonomous subject | +| a reusable capability a host runtime loads/invokes (no standalone activation) | `Skill` | a loadable host capability, not an agent | +| several members with separated duties + a routing/observation boundary | `MultiAgent` | members + coordination + governance | +| a reusable control-flow graph with no persona/system prompt | `Workflow` | the canonical graph resource | + +**`operatingType`** (Agent only, I6): conversational (back-and-forth) · automation (one-shot +end-to-end) · orchestrator (a2a-router that delegates) — INFER from intent + jobs, PROPOSE, confirm. + +### Evaluation authoring (I4 + I7) — dual entry, one close gate (D18/D19) + +- **Two valid entry paths (enforce NEITHER):** criteria-first (author binary rubric, then examples) + OR dataset-first (domain examples precede the rubric). Both must CONVERGE before emission. +- **Close gate:** confirmed `criteria[]`, `scenarios[]` (each mapped to jobs), and `datasets[]` exist. + Each dataset maps directly to jobs/scenarios/criteria, owns its **local** `categories[]` (with + `generationGuidance`) and `caseDimensions` (independent variation axes), and its `items[]` use the + selected kind's `input`/`expected` contract (Agent: response/actionCalls · Skill: outputs/hostActions + · MultiAgent: member/node outputs + actionCalls · Workflow: path/nodeOutputs). Items may be inline or + an `itemsRef` manifest. Evaluation may remain **draft** through the interview (F05) — the approved card + still shows missing links honestly. + +### Human-facing interview rules + +**Always explain:** what the question affects · why a default is proposed · what changes downstream if +the answer changes · which values are inferred vs confirmed (a document-derived value is +**inferred-with-source**, and still needs confirmation). +**Never:** cold-ask an enum without a recommendation · turn unanswered questions into invented +requirements · adopt a provided document's claim as confirmed truth without operator sign-off · dump +the whole schema as a questionnaire · hide uncertainty in free-form notes. +**Before emission:** show current truth in plain language · list decisions + rejected alternatives · +list unknowns and whether they block Build · ask for ONE explicit approve/revise response. + +**Natural conversation (binding).** This is a natural-language interview — the operator is being +*talked to like a person*, not walked through a schema. Ask for as many details as possible. Encode: +- **Talk, don't itemize.** Every question reads as something you'd say to a person, never a field-list + to fill in. **One topic at a time**, then follow up — follow-ups dig for maximal detail (keep + pulling — *"what else?"*, *"walk me through a time it went wrong"* — until the topic is richly + captured before moving on). +- **Schema vocabulary stays behind the curtain.** The card's field and bucket names (`name`, + `description`, `version`, `problem`, `outcomes`, `jobs`, `systemPrompt`, `context`, `actions`, …) + **NEVER** appear in question text. The operator answers in their own words; the interviewer maps + those answers onto the card's fields **silently**. (Proposing a closed-enum binding still happens + per the phases above — but phrased as a plain-language choice with a recommendation, never by + parading the raw enum.) +- **Contrast:** + - ✗ "Provide: Name · Description · Version." + - ✓ "Tell me about the problem you're trying to solve — what keeps going wrong, and for whom?" + +### Phase E — EMIT + GATE + +1. **Resolve the output directory** (do NOT hard-code a path). Call the output-dir resolver: + `scripts/cli/run.sh scripts/config/resolve-spec-dir.ts` — it reads `lifecycle.agentspec.spec_dir` + from `/.mutagent/config.yaml` and prints the resolved absolute `dir` + the winning `source` + (`flag`|`config`|`default`). **Precedence: flag > config > default.** With ZERO config it returns + the DEFAULT `.mutagent/specs` — so `*spec` always runs. Assemble the accumulated state into a single + `agentspec.yaml` at `//agentspec.yaml`. +2. **Optional decision sidecar (N03).** If the interview recorded consequential decisions/alternatives, + write `agentspec.decisions.md` **beside** the `agentspec.yaml` and set `spec.decisionsRef: + ./agentspec.decisions.md`. The YAML stays current truth; the Markdown holds rationale/supersession. + The pair is one portable bundle — never emit/copy only one half. +3. Run `*validate-spec ` (`scripts/validate/validate-spec.ts`) — the STRUCTURAL + SEMANTIC gate. + On FAIL, surface the field-pathed errors, return to the offending phase, fix, re-emit, re-gate. On + PASS, the card is the validated Definition + a trackable subject (a planned, not-yet-built subject is + first-class from spec-time). +4. SUGGEST the next stage (`*build`) — but NEVER auto-advance. The transition needs explicit operator + intent (PR-009). + +> **Metadata + loop position (0.3.0).** The card's identity is `metadata{id,name,version,description}` +> (subject `version` is distinct from `apiVersion` and any package release). The 0.2 `meta.loop_state` +> field is retired with the 0.2 baseline (N01); ADL loop position for a 0.3.0 subject is tracked by the +> orchestrator index OUTSIDE the card — a coordinated-update dependency (the `build-index` narrowing to +> the 0.3.0 shape rides the same FU-69 coordinated pass as the evaluator eval-contract). + +> **Output-dir note.** WHERE `*spec` writes is resolved by `scripts/config/resolve-spec-dir.ts` — +> precedence **flag > config > default**. The config field is `lifecycle.agentspec.spec_dir` in +> `/.mutagent/config.yaml` (the LOCAL install root, found by walking up to the nearest +> `.mutagent/`). The block is OPTIONAL: with no config the resolver returns the default +> `.mutagent/specs`, so `*spec` runs with zero config. A relative `spec_dir` is anchored at the config +> root; an absolute one is honored as-is. The resolver reads ONLY `spec_dir` and never cross-imports the +> orchestrator's config schema (standalone invariant). + + +--- + +## `*sync-spec` — reconcile the spec + eval triad against a target (delegated) + +> **The canonical spec-reconcile (dogfood F10).** `*sync-spec` FUSES the former `*spec-from-impl` +> (brownfield reverse-generate) and the former builder-owned `*spec-sync` (drift resync) into ONE +> operation — because reverse-generate is just *drift from nothing* (empty spec vs code). Cold (no +> `agentspec.yaml` yet → CONSTRUCT one) and warm (a spec exists but code drifted → RECONCILE the delta) +> are the SAME op with different starting points. +> +> **A THREE-leg triad (def → impl → EVAL), W2I5 · KP-003.** The reconcile keeps the spec leg AND the +> **eval-criteria leg** in lockstep with the impl (PR-011): when the impl amends, the eval criteria that +> ground the subject's evaluation can go stale exactly as the spec can. The eval leg's shape follows the +> subject kind — **eval-suite criteria** for an agent/skill subject, **code-quality criteria** for a code +> subject. `ai-architect #sync-spec` reconciles both legs; the eval-leg maintenance is the evaluator's: +> `sync-eval-criteria.ts` `reconcileEvalCriteria` COMPUTES the grown criteria set, and the evaluator session +> then PERSISTS it with `persist-eval-criteria.ts` `persistEvalCriteria` (the write that bumps the artifact's +> freshness → returns the eval leg to `in-sync`) — criteria maintenance, NOT judging; the evaluator stays +> judge-only, EV-051. +> +> **AgentSpec owns the entry but NEVER reads code.** It DELEGATES the target-read to builder's +> `ai-architect #sync-spec` (the single implementation-reader), Helix-mediated via a HandoverBundle +> (kind:agent — the same mechanism as the discovery agent). `ai-architect` returns a constructed / +> reconciled draft (spec leg + eval leg); AgentSpec `*validate-spec`-gates the spec and OWNS the result. +> Generic + subject-agnostic — no connector- or app-specific logic. + +**Inputs:** a TARGET ref — a path/repo to the existing implementation (or a cloud agent definition), +optionally its env/config surface (`.env(.example)`, framework config, manifest/package files, MCP/tool +registrations), the existing `agentspec.yaml` if one exists (warm reconcile), and the existing +eval-criteria artifact if one exists (the eval leg — auto-located under `.mutagent/evaluator/living-suite/` +when not passed). + +**Flow (parent-session, same interview discipline as `*spec`):** + +1. **Emit the delegation bundle (with the template-slot checklist).** AgentSpec builds a + `HandoverBundle{ adl_stage: build, subject:{kind:agent, name:"ai-architect"}, + intent:{command:"*sync-spec"}, inputs:[ target-ref, existing agentspec.yaml? ] }` and hands it to + Helix, which DISPATCHES builder's `ai-architect #sync-spec`. AgentSpec first derives the canonical + **template-slot checklist** deterministically — `scripts/cli/run.sh scripts/template/slot-checklist.ts + --json` (the slot skeleton of the ONE worked template, `assets/templates/agentspec.yaml.tpl`) — and + includes it in the bundle so `ai-architect` drives extraction off it: every slot deliberately FILLED + or marked N/A (the enumerate-first scaffold, PR-025). AgentSpec itself reads NO implementation source. +2. **ai-architect ENUMERATES the surface, drafts, then CROSS-VERIFIES** (builder-side, `#sync-spec` mode). + It runs the three sub-steps of the enumerate-first + cross-verify discipline (PR-025): + (a) **ENUMERATE-FIRST** — before reading the impl's own prose, LIST the real surface (every CLI + command / entrypoint / handler · hooks · files · tool/MCP/integration registrations · context sources · + sub-agents · inbound triggers · env/config), then resolve EVERY template slot from the checklist — + filled or N/A, never silently; + (b) **reverse-map + draft** — PROJECT the enumerated surface onto the 0.3.0 `spec` blocks: the intent + (`intent.problem/outcomes/sop/jobs/…`), `context[]` (+ `access`), `actions[]`, `capabilities` + (code/skills/delegates), and the ONE kind-native body — for an Agent: `agent.persona` + + `agent.systemPrompt` (impl's operative text VERBATIM, PR-014), `agent.operatingType` (INFER + PROPOSE + per F2), `agent.triggers`, and an optional canonical `agent.workflow` — seeding `evaluation` from jobs + + observed behavior; INFER the observed `spec.targets[]` (type/name/`artifact.format`) from the impl + (the one case where the target is observed, not chosen). Read files in full — do not guess from + filenames. Cold → construct from scratch; warm → emit the reconcile DELTA against the existing spec; + (c) **CROSS-VERIFY** — an LLM pass comparing the drafted spec back against the enumerated surface (the + **impl→spec** direction, which `spec-impl-coverage.ts` — spec→impl only — has no home for), reporting + every surface item present but MISSING/partial in the draft. Returns a `HandoverBundle` carrying the + draft/reconciled `agentspec.yaml` + the enumerated-surface checklist (each slot's disposition) + the + cross-verify report. +3. **CONFIRM the draft — including the omissions — with the operator.** AgentSpec surfaces every INFERRED + field as a proposal (AskUserQuestion / chat fallback) AND surfaces the cross-verify report UP FRONT — + the surface items present but missing/partial in the draft, and each slot marked N/A — so the operator + sees what was included AND excluded, and decides, rather than discovering an omission after the fact. A + reverse-generated draft is a proposal, never a silent fact; the operator owns the final Definition (the + same parent-session, propose-don't-assume discipline as `*spec`). +4. **Emit + GATE + own.** AgentSpec writes the 0.3.0 `agentspec.yaml` (loop position tracked OUTSIDE the + card — the 0.2 `meta.loop_state` is retired, N01; the tracking mechanism rides the coordinated FU-69 + pass) and runs `*validate-spec`. On FAIL, surface the field-pathed errors, fix the offending block, re-emit, re-gate. + On PASS, the reconciled spec is a trackable Definition AgentSpec OWNS — `*build` re-running against it + now cascade-updates the impl (def → impl, PR-001). When the sync yields spec WRITES that touch the + impl, `ai-engineer` applies them (gated). +5. **Reconcile the EVAL leg (the third leg, W2I5).** When `ai-architect`'s freshness probe flags the eval + leg (`driftedLegs` contains `eval` — the impl amended past the eval criteria), it also drafts an + eval-criteria reconcile delta for the applicable leg (eval-suite criteria for an agent/skill subject, + code-quality criteria for a code subject). AgentSpec surfaces the delta to the operator (propose, + don't assume) exactly as for a spec field, then the **evaluator's criteria-maintenance hook** + (`reconcileEvalCriteria`) COMPUTES the grown set under the gate — an append-only upsert that never drops a + criterion (EV-053) — and the **evaluator session PERSISTS** `result.criteria` to the located artifact + (`persist-eval-criteria.ts` `persistEvalCriteria` → `.mutagent/evaluator/living-suite/.criteria.json`). + The hook COMPUTES; the persist is the WRITE — and that write bumps the artifact's freshness, which is what + returns the eval leg to `in-sync`. This is criteria maintenance, NOT judging; the evaluator stays + judge-only (EV-051). The spec leg and the eval leg move together so def → impl → eval never falls out of + lockstep. +6. **Re-probe to confirm in-sync (closing self-heal).** After the gated writes land (spec via `ai-engineer`, + eval criteria via `persistEvalCriteria`), RE-RUN the freshness probe (`check-sync-spec.ts`) one final time. + The procedure only completes when it reports `in-sync` on every leg that drifted (`driftedLegs` empty); + `eval` still in `driftedLegs` means the criteria write was skipped or landed stale — the re-probe SURFACES + it so the persist can be re-run, rather than closing `*sync-spec` on an unpersisted (still-drifted) leg. + +> **Scope (subject-agnostic).** `*sync-spec` reads an arbitrary implementation surface (via +> `ai-architect`); it embeds NO per-connector / per-app logic. The drift is detected by a deterministic +> code predicate (`check-sync-spec.ts`, spec + eval legs); the reconcile itself is `ai-architect` +> reasoning, session-dispatched (Model-B — code detects, the agent reconciles). Builder ALSO reuses +> `ai-architect #sync-spec` build-internally when it detects drift mid-`*build`. + +### Reverse-sync (Optimize-first) — the 0.3.0 no-silent-overwrite gate + +⑤ OPTIMIZE may change implementation code **first**; the 0.3.0 card must then be reconciled **without +letting code silently redefine intent**. Code is useful evidence, not the design authority — the +operator remains the owner of *why* and *intended behavior*. The reverse-sync run: + +1. **Read the impl** — `ai-architect #sync-spec` (the single implementation-reader) reads the changed + surface read-only and produces an **explicit proposed delta at three levels**: (a) 0.3.0 **field** + changes (which `spec.*` keys change and to what), (b) **decision-log** entries for consequential + choices (append to `agentspec.decisions.md`, with supersession where a prior decision is overturned), + and (c) **eval-criterion** changes (the eval leg, per the triad). Every proposed change **cites** the + impl evidence. +2. **Operator gate — approve / revise / reject.** NEVER auto-apply. A **rejected** proposal leaves the + card and sidecar **unchanged** (no silent overwrite). A **revised** proposal is re-drafted. +3. **Persist only approved deltas** — write the approved field changes into `agentspec.yaml`, the + approved rationale into `agentspec.decisions.md` (keeping `spec.decisionsRef` and the YAML consistent + — never publish/copy only one half), and the approved eval-criteria via the evaluator's persist path. +4. **Validate + re-probe to empty drift** — `*validate-spec` (structural+semantic) must pass on the + updated card, then RE-RUN `check-sync-spec.ts` until **every** drifted leg reports `in-sync` + (`driftedLegs` empty). The run only completes on an empty drift set. + +**Proof (exit check):** a code-side change produces a cited spec/decision/eval proposal, records the +operator disposition, persists only approved truth, keeps YAML↔sidecar consistent, and ends with an +empty drift set. A rejected proposal leaves truth untouched. + +--- + +## `*validate-spec` — the schema gate (script) + +`kind: script` · `binds: scripts/validate/validate-spec.ts`. Reads a YAML spec path, parses it, +validates against the frozen `agentspec.mutagent.io/v0.3.0` contract — STRUCTURAL (`scripts/contract/agentspec.schema.ts`) then SEMANTIC (`scripts/validate/semantic-validator.ts`) — +prints field-pathed errors + exits non-zero on failure, or `[validate-spec] PASS` + exit 0 on +success. The worked template (`assets/templates/agentspec.yaml.tpl`) is asserted valid by the +test suite — copy it as a starting point. + +--- + +## `*build` — handoff to BUILD (`mutagent-builder`) + +`mutagent-agentspec` validates and emits `agentspec.yaml`. The next explicit operator command is +`*build`, routed by Helix to `mutagent-builder`. BUILD consumes the validated Definition, reuses +`ai-architect #sync-spec` build-internally when it detects drift, dispatches `ai-engineer` / +`ai-architect`, runs TDD + spec implementation coverage, and emits the build report + EVALUATE handoff +bundle. (The `*sync-spec` COMMAND is now owned by `mutagent-agentspec` — it delegates the same +`ai-architect #sync-spec` read.) + +Agentspec does **not** keep an executable build owner row, build agents, or coverage gate. Its boundary +ends at a schema-valid spec plus the handoff suggestion. + +--- + +## `*eval` — eval-driven development handoff (OUTLINED — Wave-3) + +> A designed FEATURE at the doc/protocol level only — never a code import (PR-018). `mutagent-agentspec` +> does NOT depend on an evaluator skill to run standalone. + +**Shape:** hand the built agent + its `spec.evaluation.criteria` (+ `scenarios`/`datasets`, D18/D19) to +an evaluator (the ADL EVALUATE stage) for eval-driven development. The spec's evaluation criteria SEED +the evaluator's eval-matrix (link, don't duplicate). When composed via Helix, `*eval` routes to the evaluator +skill; standalone, agentspec emits the eval criteria + (optionally) a thin self-contained eval stub. +The triad (spec ↔ impl ↔ eval) stays in lockstep with auto-spec-correction (PR-011) — the mechanism +lands with this stage. + +--- + +## Loop position + transitions (PR-009) + +The orchestrator KNOWS the next stage and proactively SUGGESTS it + renders loop position (tracked +OUTSIDE the 0.3.0 card — the 0.2 `meta.loop_state.stage` is retired, N01; the tracking mechanism rides +the coordinated FU-69 pass), but EVERY transition needs explicit operator confirmation. "Auto-orchestrate" +means suggest, never auto-run. Never auto-advance through a gate. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/doctor.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/doctor.ts new file mode 100644 index 00000000..81a6cde0 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/doctor.ts @@ -0,0 +1,116 @@ +/** + * scripts/cli/doctor.ts + * Runtime probe + JSON health report. + * Type A — Pure Script (deterministic environment inspection). + * + * Detects the JS runtime (bun | pnpm-tsx | npx-tsx | node), reports the SKILL.md version, the + * lock-file present in the skill root, and whether git is available. agentspec has NO external + * provider deps (no Langfuse/Google), so there is NO required-env-var probe — keeping doctor lean. + * + * Usage: scripts/cli/run.sh scripts/cli/doctor.ts + * Output: { runtime, version, lockFile, gitAvailable, errors[] } + */ + +import { existsSync, readFileSync, realpathSync } from "node:fs"; +import { execSync } from "node:child_process"; +import { join, resolve } from "node:path"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +export type DoctorRuntime = "bun" | "pnpm-tsx" | "npx-tsx" | "node"; + +export interface DoctorReport { + /** JS runtime executing this skill's scripts. */ + runtime: DoctorRuntime; + /** Skill version string from SKILL.md frontmatter/metadata, or null if unreadable. */ + version: string | null; + /** Lock-file detected in the skill root, or null. */ + lockFile: string | null; + /** Whether `git` is available in PATH. */ + gitAvailable: boolean; + /** Non-fatal warnings. Exit code is still 0. */ + errors: string[]; +} + +/** + * Detect the JS runtime executing this script. + * 1. Bun: process.versions.bun set under Bun. + * 2. pnpm-tsx: npm_config_user_agent starts with "pnpm". + * 3. npx-tsx: npm_execpath set (npm/npx). + * 4. node: bare node fallback. + */ +export function detectJsRuntime(): DoctorRuntime { + const versions = process.versions as Record; + if (versions.bun) return "bun"; + const userAgent = process.env.npm_config_user_agent ?? ""; + if (userAgent.startsWith("pnpm")) return "pnpm-tsx"; + if (process.env.npm_execpath) return "npx-tsx"; + return "node"; +} + +/** + * Read the skill version from SKILL.md (the `version:` key, possibly indented under `metadata:`). + * Returns null if SKILL.md is absent or the version field is missing. + * SKILL.md lives at /SKILL.md; this script is at /scripts/cli/doctor.ts. + */ +export function readSkillVersion(scriptDir: string): string | null { + const skillMd = resolve(scriptDir, "../..", "SKILL.md"); + if (!existsSync(skillMd)) return null; + try { + const content = readFileSync(skillMd, "utf8"); + const match = content.match(/^\s*version:\s*["']?([^"'\n\r]+?)["']?\s*$/m); + return match ? match[1].trim() : null; + } catch { + return null; + } +} + +/** Detect the first lock file present in `dir`. */ +export function detectLockFile(dir: string): string | null { + const candidates = ["bun.lockb", "bun.lock", "pnpm-lock.yaml", "package-lock.json", "yarn.lock"]; + for (const name of candidates) { + if (existsSync(join(dir, name))) return name; + } + return null; +} + +/** Check whether `git` is available in PATH. */ +export function checkGitAvailable(): boolean { + try { + execSync("git --version", { stdio: "ignore" }); + return true; + } catch { + return false; + } +} + +/** Run the full doctor probe and return a structured report. Never throws. */ +export function runDoctor(): DoctorReport { + const errors: string[] = []; + const scriptDir = realpathSync( + import.meta.dirname ?? + import.meta.url.replace(/^file:\/\//, "").replace(/\/[^/]+$/, ""), + ); + + const runtime = detectJsRuntime(); + const version = readSkillVersion(scriptDir); + const lockFile = detectLockFile(resolve(scriptDir, "../..")); + const gitAvailable = checkGitAvailable(); + + if (!gitAvailable) { + errors.push("git not found in PATH — branch-hygiene operations will fail"); + } + if (version === null) { + errors.push("Could not read SKILL.md version"); + } + + return { runtime, version, lockFile, gitAvailable, errors }; +} + +// ── CLI entrypoint ──────────────────────────────────────────────────────────── +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + const report = runDoctor(); + process.stdout.write(JSON.stringify(report, null, 2) + "\n"); + process.exit(0); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/init.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/init.ts new file mode 100644 index 00000000..261103d5 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/init.ts @@ -0,0 +1,230 @@ +/** + * scripts/cli/init.ts + * LEAN cross-platform installer for mutagent-agentspec. + * Invoked as: pnpx @mutagent/agentspec init + * + * Wave-1 keeps this minimal — NO onboarding FSM (that is a later wave). init's whole job: + * 1. Detect installed coding-agent platforms via home markers (~/.claude, ~/.codex). + * 2. Copy the skill tree into the install target: + * project (DEFAULT) → /.claude/skills/mutagent-agentspec (and .codex) + * global (--global) → ~/.claude/skills/mutagent-agentspec (and ~/.codex) + * 3. Copy the two shipped sub-agent contracts (assets/agents/*.md) into /.claude/agents. + * + * cwd discipline: the SOURCE skill dir is resolved from import.meta (correct through any symlink + * chain); the install TARGET root is the user's invocation cwd (process.cwd()), NEVER the script + * dir — overriding it would install the skill into itself. + */ + +import { + existsSync, + readdirSync, + mkdirSync, + cpSync, + copyFileSync, + realpathSync, +} from "node:fs"; +import { join, resolve } from "node:path"; +import { homedir } from "node:os"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +export type Scope = "project" | "global"; +export type PlatformId = "claude-code" | "codex"; + +export interface DetectedPlatform { + id: PlatformId; + label: string; + /** Home marker probed to decide whether the platform exists on this machine. */ + detectionMarker: string; + detected: boolean; + /** Where the skill tree is installed (follows scope). */ + skillInstallPath: string; + /** Where the sub-agent .md files are installed (follows scope). */ + agentsInstallPath: string; +} + +export interface PlatformInstallResult { + platform: PlatformId; + success: boolean; + steps: Array<{ step: string; ok: boolean; note: string }>; + errors: string[]; +} + +/** Resolve install scope from argv. DEFAULT is project-local; `--global` opts into the home dir. */ +export function resolveScope(argv: string[]): Scope { + return argv.includes("--global") ? "global" : "project"; +} + +/** + * Probe the filesystem for installed coding-agent platforms. Detection uses HOME markers (does the + * runtime exist on this machine?); the install TARGET follows `scope`: + * project (DEFAULT) → /.claude|.codex/… global → /.claude|.codex/… + */ +export function detectInstalledPlatforms( + cwd: string = process.cwd(), + scope: Scope = "project", + home: string = homedir(), +): DetectedPlatform[] { + const claudeRoot = scope === "global" ? join(home, ".claude") : join(cwd, ".claude"); + const codexRoot = scope === "global" ? join(home, ".codex") : join(cwd, ".codex"); + return [ + { + id: "claude-code", + label: "Claude Code", + detectionMarker: join(home, ".claude"), + detected: existsSync(join(home, ".claude")), + skillInstallPath: join(claudeRoot, "skills", "mutagent-agentspec"), + agentsInstallPath: join(claudeRoot, "agents"), + }, + { + id: "codex", + label: "Codex", + detectionMarker: join(home, ".codex"), + detected: existsSync(join(home, ".codex")), + skillInstallPath: join(codexRoot, "skills", "mutagent-agentspec"), + agentsInstallPath: join(codexRoot, "agents"), + }, + ]; +} + +/** + * Install the skill + its sub-agent contracts to a single platform. + * Pure-ish: all filesystem effects are scoped to the platform's install paths; the source dir is + * injected so the function is testable against temp trees. + */ +export function installToPlatform( + platform: DetectedPlatform, + skillSourceDir: string, + force = false, +): PlatformInstallResult { + const result: PlatformInstallResult = { + platform: platform.id, + success: false, + steps: [], + errors: [], + }; + + // ── Step 1: copy the skill tree ────────────────────────────────────────────── + const skillDest = platform.skillInstallPath; + try { + if (existsSync(skillDest) && !force) { + result.steps.push({ + step: "copy-skill", + ok: true, + note: `Skill already exists at ${skillDest} (use --force to overwrite).`, + }); + } else { + mkdirSync(skillDest, { recursive: true }); + cpSync(skillSourceDir, skillDest, { recursive: true, force: true }); + result.steps.push({ step: "copy-skill", ok: true, note: `Copied skill to ${skillDest}.` }); + } + } catch (err) { + const msg = `Failed to copy skill to ${skillDest}: ${err instanceof Error ? err.message : String(err)}`; + result.steps.push({ step: "copy-skill", ok: false, note: msg }); + result.errors.push(msg); + return result; + } + + // ── Step 2: copy the shipped sub-agent contracts ───────────────────────────── + const agentsSrc = join(skillSourceDir, "assets", "agents"); + const agentsDest = platform.agentsInstallPath; + try { + if (existsSync(agentsSrc)) { + const agentFiles = readdirSync(agentsSrc).filter((f) => f.endsWith(".md")); + mkdirSync(agentsDest, { recursive: true }); + for (const f of agentFiles) { + copyFileSync(join(agentsSrc, f), join(agentsDest, f)); + } + result.steps.push({ + step: "install-agents", + ok: true, + note: `Installed ${agentFiles.length} sub-agent contract(s) to ${agentsDest}.`, + }); + } else { + result.steps.push({ step: "install-agents", ok: true, note: "No assets/agents/ — skipped." }); + } + } catch (err) { + const msg = `Failed to install agents to ${agentsDest}: ${err instanceof Error ? err.message : String(err)}`; + result.steps.push({ step: "install-agents", ok: false, note: msg }); + result.errors.push(msg); + } + + result.success = result.errors.length === 0; + return result; +} + +// ── Usage ───────────────────────────────────────────────────────────────────── +const USAGE = ` +mutagent-agentspec init — cross-platform skill installer + +USAGE + pnpx @mutagent/agentspec init [--global] [--yes] [--force] + +INSTALL SCOPE + (default) PROJECT-LOCAL — install into the directory you ran init in: + Claude Code → /.claude/… Codex → /.codex/… + --global HOME DIR — install into ~/.claude/… and ~/.codex/… + +OPTIONS + --global Install into the home dir instead of the project (default: project-local) + --yes Non-interactive: install to all detected platforms + --force Overwrite an existing skill install + --help Show this message + +After install, open your coding agent and invoke the skill, then *spec to begin. +`.trim(); + +// ── CLI entrypoint ────────────────────────────────────────────────────────────── +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + const argv = (typeof Bun !== "undefined" ? Bun.argv : process.argv).slice(2); + + if (argv.includes("--help") || argv.includes("-h")) { + process.stdout.write(USAGE + "\n"); + process.exit(0); + } + + const scope = resolveScope(argv); + const force = argv.includes("--force"); + const cwd = process.cwd(); + + // SOURCE skill dir = two levels up from scripts/cli/ (resolved through symlinks). + const scriptDir = realpathSync( + import.meta.dirname ?? + import.meta.url.replace(/^file:\/\//, "").replace(/\/[^/]+$/, ""), + ); + const skillDir = resolve(scriptDir, "..", ".."); + + const platforms = detectInstalledPlatforms(cwd, scope).filter((p) => p.detected); + if (platforms.length === 0) { + process.stderr.write( + "[init] No coding-agent platforms detected (~/.claude or ~/.codex).\n" + + " Install Claude Code or Codex first, then re-run init.\n", + ); + process.exit(1); + } + + process.stdout.write( + `[init] Install scope: ${scope}${scope === "project" ? ` (${cwd})` : " (home dir)"}\n`, + ); + + let anyFailure = false; + for (const platform of platforms) { + process.stdout.write(`\n[init] Installing to ${platform.label}...\n`); + const r = installToPlatform(platform, skillDir, force); + for (const step of r.steps) { + process.stdout.write(` ${step.ok ? "ok" : "FAIL"} ${step.step}: ${step.note}\n`); + } + if (r.success) { + process.stdout.write(`[init] ${platform.label}: install complete.\n`); + if (platform.id === "claude-code") { + process.stdout.write(" Restart your Claude Code session, then invoke *spec.\n"); + } + } else { + process.stderr.write(`[init] ${platform.label}: FAILED — ${r.errors.join("; ")}\n`); + anyFailure = true; + } + } + + process.exit(anyFailure ? 1 : 0); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/run.sh b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/run.sh new file mode 100644 index 00000000..2bd63f23 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/cli/run.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# scripts/cli/run.sh — bun→pnpm→npm fallback selector + .sh dispatch. +# Usage: scripts/cli/run.sh [args...] +# scripts/cli/run.sh --selftest +# +# This wrapper provides consistent script invocation across operator environments. +# All agent Bash() calls to TypeScript OR shell scripts MUST go through this wrapper: +# Bash("scripts/cli/run.sh scripts/validate/validate-spec.ts ...") +# +# Platform matrix — which tier fires when: +# Tier 1 (bun) : bun is on PATH (local dev, most operator installs) +# Tier 2 (pnpm-tsx) : bun absent, pnpm on PATH (corporate Node setups, pnpm-only CIs) +# Tier 3 (npx-tsx) : bun + pnpm absent, npx on PATH (vanilla Node, GitHub Actions default) +# Tier 4 (error) : none of the above — exits 1 with install guidance +# .sh scripts bypass all tiers and run directly via bash regardless of PATH state. + +set -e + +SCRIPT="$1" + +# --selftest: print selected runtime and exit 0 (portability probe) +if [ "$SCRIPT" = "--selftest" ]; then + if command -v bun >/dev/null 2>&1; then + echo "run.sh selftest: tier=1 runtime=bun version=$(bun --version 2>/dev/null || echo unknown)" + elif command -v pnpm >/dev/null 2>&1; then + echo "run.sh selftest: tier=2 runtime=pnpm-tsx version=$(pnpm --version 2>/dev/null || echo unknown)" + elif command -v npx >/dev/null 2>&1; then + echo "run.sh selftest: tier=3 runtime=npx-tsx version=$(node --version 2>/dev/null || echo unknown)" + else + echo "run.sh selftest: tier=4 runtime=none (install bun: curl -fsSL https://bun.sh/install | bash)" + exit 1 + fi + exit 0 +fi + +shift + +if [ -z "$SCRIPT" ]; then + echo "ERROR: no script path provided" >&2 + echo "Usage: run.sh [args...]" >&2 + echo " run.sh --selftest" >&2 + exit 1 +fi + +# .sh files: execute directly via bash (no TS runtime needed) +case "$SCRIPT" in + *.sh) exec bash "$SCRIPT" "$@" ;; +esac + +# A runtime that resolves under /mnt/* is a WINDOWS exe reached through WSL +# interop — it cannot accept the POSIX paths this selector passes (observed: +# WSL node + Windows-side pnpm → /home/... re-anchored to C:\home\... → +# ERR_MODULE_NOT_FOUND). Skip it so a native tier runs instead. +native_cmd() { + _p="$(command -v "$1" 2>/dev/null)" || return 1 + case "$_p" in /mnt/*) return 1 ;; esac + return 0 +} + +if native_cmd bun; then + exec bun run "$SCRIPT" "$@" +elif native_cmd pnpm; then + echo "[run.sh] runtime tier 2: pnpm dlx tsx (bun not on PATH). TypeScript entrypoints use the portable isEntrypoint() guard." >&2 + exec pnpm dlx tsx "$SCRIPT" "$@" +elif native_cmd npx; then + echo "[run.sh] runtime tier 3: npx tsx (bun and pnpm not on PATH). TypeScript entrypoints use the portable isEntrypoint() guard." >&2 + exec npx -y tsx "$SCRIPT" "$@" +else + echo "ERROR: mutagent-agentspec requires bun, pnpm, or npm/npx to run TypeScript scripts" >&2 + echo "Install bun: curl -fsSL https://bun.sh/install | bash" >&2 + exit 1 +fi diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts new file mode 100644 index 00000000..6ef27ce0 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/config/resolve-spec-dir.ts @@ -0,0 +1,199 @@ +/** + * scripts/config/resolve-spec-dir.ts + * The `*spec` OUTPUT-DIR resolver — decides WHERE the interview writes `agentspec.yaml`. + * Type A — Pure Script (a pure resolver + a thin guarded CLI). + * + * Resolution precedence (first non-empty wins): + * 1. flag — an explicit `--spec-dir ` / caller override (highest authority) + * 2. config — `lifecycle.agentspec.spec_dir` in `/.mutagent/config.yaml` + * 3. default — `.mutagent/specs` (the canonical tree; specs//agentspec.yaml) + * + * ZERO-CONFIG is a first-class case: `*spec` MUST run with no `.mutagent/config.yaml` at all. + * A missing config file, a config without a `lifecycle.agentspec` block, or a block without + * `spec_dir` ALL fall through to the default. Only a genuinely present, non-empty string in the + * config overrides the default. + * + * MINIMAL BY DESIGN (do not over-build): this reads ONLY `parsed.lifecycle.agentspec?.spec_dir`. + * It is NOT a full config schema port — agentspec stays standalone and never cross-imports the + * orchestrator's config-schema (the standalone + symbiosis invariant). The one field the orchestrator + * TYPES for this skill (`lifecycle.agentspec.spec_dir`, an optional string) is the only thing read. + * + * CONFIG FIELD — `lifecycle.agentspec.spec_dir` (optional string): + * CONSUMER: THIS resolver (`resolveSpecOutputDir` → `readSpecDirFromConfig`), invoked by the + * agentspec `*spec` interview to pick its write root. No other skill reads it. + * PURPOSE: precedence tier 2 — overrides the default `.mutagent/specs` tree so an operator can + * relocate where `agentspec.yaml` lands (e.g. a monorepo-shared specs dir). A relative + * value anchors at the config root; an absolute value is honored as-is; absent/blank ⇒ + * the default (zero-config stays first-class). Never a secret — a plain path string. + * + * The config ROOT is the nearest ancestor of `startDir` that already contains a `.mutagent/` + * directory (mirrors the orchestrator's resolve-paths.ts `findConfigRoot`); when none exists the + * start dir is used (first-run friendly — that is where `init` will create `.mutagent/`). The + * default `spec_dir` is resolved RELATIVE to that root; a relative config value is likewise anchored + * at the root, an absolute config value is honored as-is. + * + * Usage: scripts/cli/run.sh scripts/config/resolve-spec-dir.ts [--spec-dir ] [startDir] + * Prints the resolved absolute output directory + the source that won (flag|config|default). + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { parse as parseYaml } from "yaml"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +/** The single local root dir name. Never `~/.mutagent`. (mirrors resolve-paths.ts) */ +export const MUTAGENT_DIR = ".mutagent" as const; + +/** The default `spec_dir` when config is absent/optional — relative to the config root. */ +export const DEFAULT_SPEC_DIR = path.join(MUTAGENT_DIR, "specs"); + +/** Which input won the resolution — surfaced so the CLI + callers can report precedence. */ +export type SpecDirSource = "flag" | "config" | "default"; + +export interface ResolvedSpecDir { + /** The resolved output directory, absolute. `*spec` writes `//agentspec.yaml`. */ + dir: string; + /** Which precedence tier supplied the value. */ + source: SpecDirSource; + /** The install/config root the default (and any relative value) was anchored at. */ + root: string; +} + +/** Minimal injectable fs surface — keeps the resolver pure + deterministically testable. */ +export interface ResolveFs { + /** True iff `p` exists and is a directory (used to find the `.mutagent/` root). */ + dirExists: (p: string) => boolean; + /** True iff `p` exists and is a readable file (the config file). */ + fileExists: (p: string) => boolean; + /** Read a UTF-8 file (only called when `fileExists` is true). */ + readText: (p: string) => string; +} + +/** Live fs binding — real `node:fs`, for the CLI + production callers. */ +export const liveFs: ResolveFs = { + dirExists: (p) => { + try { + return fs.statSync(p).isDirectory(); + } catch { + return false; + } + }, + fileExists: (p) => { + try { + return fs.statSync(p).isFile(); + } catch { + return false; + } + }, + readText: (p) => fs.readFileSync(p, "utf-8"), +}; + +/** + * Walk UP from `startDir` to the nearest ancestor that already contains a `.mutagent/` directory; + * return that ancestor (the install/init root). If none is found, return the resolved `startDir` + * (first run — `init` creates `.mutagent/` there). Pure: directory existence is injected. + * Mirrors the orchestrator resolve-paths.ts `findConfigRoot` (NOT imported — standalone invariant). + */ +export function findConfigRoot(startDir: string, dirExists: (p: string) => boolean): string { + let dir = path.resolve(startDir); + // Bounded by the filesystem root — path.dirname("/") === "/" terminates the loop. + for (;;) { + if (dirExists(path.join(dir, MUTAGENT_DIR))) return dir; + const parent = path.dirname(dir); + if (parent === dir) break; + dir = parent; + } + return path.resolve(startDir); +} + +/** + * Read ONLY `lifecycle.agentspec.spec_dir` out of a config YAML string. Returns the trimmed string + * when present + non-empty, else `undefined`. NEVER throws: a YAML parse error, a non-object shape, + * a missing `lifecycle`/`agentspec` block, or a non-string / blank `spec_dir` all yield `undefined` + * (→ the caller falls back to the default). This is the whole "config loader" — minimal by design. + */ +export function readSpecDirFromConfig(configText: string): string | undefined { + let parsed: unknown; + try { + parsed = parseYaml(configText); + } catch { + return undefined; + } + if (parsed === null || typeof parsed !== "object") return undefined; + const lifecycle = (parsed as Record).lifecycle; + if (lifecycle === null || typeof lifecycle !== "object") return undefined; + const agentspec = (lifecycle as Record).agentspec; + if (agentspec === null || typeof agentspec !== "object") return undefined; + const specDir = (agentspec as Record).spec_dir; + if (typeof specDir !== "string") return undefined; + const trimmed = specDir.trim(); + return trimmed.length > 0 ? trimmed : undefined; +} + +/** Anchor a spec-dir value at the config root: absolute values pass through, relative anchor at root. */ +function anchor(root: string, value: string): string { + return path.isAbsolute(value) ? path.resolve(value) : path.resolve(root, value); +} + +export interface ResolveSpecOutputDirOptions { + /** Where resolution starts (find the `.mutagent/` root from here). Defaults to process.cwd(). */ + startDir?: string; + /** An explicit override (precedence tier 1) — e.g. from a `--spec-dir` flag. */ + flag?: string; + /** Injected fs surface — defaults to the live `node:fs` binding. */ + fsImpl?: ResolveFs; +} + +/** + * Resolve the `*spec` output directory. Precedence: flag > config > default (`.mutagent/specs`). + * Pure w.r.t. the injected `fsImpl`; the default binding hits real `node:fs`. + */ +export function resolveSpecOutputDir(options: ResolveSpecOutputDirOptions = {}): ResolvedSpecDir { + const startDir = options.startDir ?? process.cwd(); + const fsImpl = options.fsImpl ?? liveFs; + + const root = findConfigRoot(startDir, fsImpl.dirExists); + + // Tier 1 — an explicit flag/override always wins. + const flag = options.flag?.trim(); + if (flag !== undefined && flag.length > 0) { + return { dir: anchor(root, flag), source: "flag", root }; + } + + // Tier 2 — the config value, iff a config file exists AND carries a non-empty spec_dir. + const configFile = path.join(root, MUTAGENT_DIR, "config.yaml"); + if (fsImpl.fileExists(configFile)) { + const fromConfig = readSpecDirFromConfig(fsImpl.readText(configFile)); + if (fromConfig !== undefined) { + return { dir: anchor(root, fromConfig), source: "config", root }; + } + } + + // Tier 3 — the default. Zero-config path lands here. + return { dir: anchor(root, DEFAULT_SPEC_DIR), source: "default", root }; +} + +// ── CLI ───────────────────────────────────────────────────────────────────────── +function runCli(argv: string[]): number { + const args = argv.slice(2); + const flagIdx = args.indexOf("--spec-dir"); + const flag = flagIdx >= 0 ? args[flagIdx + 1] : undefined; + // The first non-flag positional (skipping the flag itself + its value) is the startDir override. + const flagValueIdx = flagIdx >= 0 ? flagIdx + 1 : -1; + const positional = args.find( + (a, i) => !a.startsWith("--") && i !== flagIdx && i !== flagValueIdx, + ); + + const resolved = resolveSpecOutputDir({ startDir: positional, flag }); + console.info(`[resolve-spec-dir] dir: ${resolved.dir}`); + console.info(`[resolve-spec-dir] source: ${resolved.source}`); + console.info(`[resolve-spec-dir] root: ${resolved.root}`); + return 0; +} + +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + const argv = typeof Bun !== "undefined" ? Bun.argv : process.argv; + process.exit(runCli(argv)); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts new file mode 100644 index 00000000..254139dc --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/contract/agentspec.schema.ts @@ -0,0 +1,830 @@ +/** + * scripts/contract/agentspec.schema.ts + * TypeBox schema + TypeScript types for the portable agentspec.yaml — AgentSpec 0.3.0. + * Type A — Pure Script (schema + types + a pure validate function — no I/O side effects). + * + * AgentSpec 0.3.0 is the FIRST canonical versioned baseline (N01/F01 — no 0.2 migration/history). + * It is ONE closed resource envelope with a strict `kind` discriminator: + * + * apiVersion: agentspec.mutagent.io/v0.3.0 # compatibility contract (D12), not a package version + * kind: Agent | Skill | MultiAgent | Workflow # inferred AFTER intent (D01/D03) + * metadata: { id · name · version · description } # one coherent card identity + * spec: # requirements-first, target-independent + * intent — problem · outcomes · long-form SOP (before derived jobs) · constraints · + * nonGoals · assumptions · unknowns (requirements-first Intent) + * context[] — inbound information + its read access, together (D16) + * actions[] — outbound side effects: binding · approval · evidence · onFailure (D16) + * capabilities — local code · loadable skills · delegates (requirements before targets) + * — EXACTLY ONE of agent | skill | multiAgent | workflow (D01/D03) + * targets[] — one or more destinations + artifact.format/path (supersedes `medium`, FU-69) + * evaluation — criteria · scenarios · datasets (dataset-local categories, D18/D19) + * decisionsRef? — optional relative pointer to one colocated agentspec.decisions.md (N03) + * + * STRUCTURAL vs SEMANTIC. This file is the STRUCTURAL floor: every object is CLOSED + * (additionalProperties:false) so undeclared fields (a typo or a smuggled block) are REJECTED + * (F02 fully-closed core). It intentionally does NOT enforce cross-reference / graph / cycle / + * bounded-loop / kind-leakage rules — those are the SEMANTIC layer in `../validate/semantic-validator.ts` + * (the exit checks: unknown fields fail · kind leakage fails · member cycles fail · bounded Workflow + * loops pass · target/decision-file/context-action/dataset references resolve). + * + * Mirrors the handover-contract.ts pattern: a compiled TypeCompiler checker + a pure + * `validateAgentSpec(obj) => { ok, errors[] }`. Fail-loud, never throws. + */ + +import { type Static, Type } from "@sinclair/typebox"; +import { TypeCompiler } from "@sinclair/typebox/compiler"; + +/** + * The FROZEN compatibility identifier (D12/F01). Fail loudly on any incompatible shape. + * 0.3.0 is the first canonical versioned baseline — there is no previous-version or migration field. + */ +export const AGENTSPEC_API_VERSION = "agentspec.mutagent.io/v0.3.0" as const; +/** The bare semantic version, for tooling that wants it without the domain prefix. */ +export const AGENTSPEC_SCHEMA_VERSION = "0.3.0" as const; + +// ── Categorical constants (no magic strings) ─────────────────────────────────── + +/** Top-level resource taxonomy — inferred after intent, used as a strict discriminator (D01/D03). */ +export const Kind = { + Agent: "Agent", + Skill: "Skill", + MultiAgent: "MultiAgent", + Workflow: "Workflow", +} as const; +export type KindValue = (typeof Kind)[keyof typeof Kind]; + +/** How an Agent operates (Agent-body only). */ +export const OperatingType = { + Conversational: "conversational", + Automation: "automation", + Orchestrator: "orchestrator", +} as const; +export type OperatingTypeValue = (typeof OperatingType)[keyof typeof OperatingType]; + +/** How an Agent is ACTIVATED — inbound event sources (Agent-body only). */ +export const TriggerKind = { + A2a: "a2a", + Webhook: "webhook", + Schedule: "schedule", + Queue: "queue", + Event: "event", + Mcp: "mcp", + Manual: "manual", +} as const; +export type TriggerKindValue = (typeof TriggerKind)[keyof typeof TriggerKind]; + +/** Eval criterion check type — binary-actionable (D19). */ +export const EvalType = { + LlmJudge: "llm-judge", + CodeCheck: "code-check", +} as const; +export type EvalTypeValue = (typeof EvalType)[keyof typeof EvalType]; + +/** + * The CLOSED binding-kind vocabulary for context `access` and action `binding` (operator ruling R3, + * 2026-07-22). A kind outside this set FAILS validation (fail-loud, consistent with F02's closed + * core). Future kinds arrive via a 0.3.x minor bump — never by silently accepting an unknown string. + */ +export const BindingKind = { + Cli: "cli", + Saas: "saas", + Mcp: "mcp", + Sdk: "sdk", + HostTool: "host-tool", +} as const; +export type BindingKindValue = (typeof BindingKind)[keyof typeof BindingKind]; + +/** + * The CLOSED executor-kind vocabulary for a Workflow node's typed executor (F03 LOCKED; operator + * ruling R4, 2026-07-22). A step invokes a member, an Agent/Skill capability, a bounded action, an + * integration, or a code operation. Required INPUT (context reads) stays SEPARATE on the node as + * `contextRefs` — it is NOT an executor form. + */ +export const ExecutorKind = { + Member: "member", + Agent: "agent", + Skill: "skill", + Action: "action", + Integration: "integration", + Code: "code", +} as const; +export type ExecutorKindValue = (typeof ExecutorKind)[keyof typeof ExecutorKind]; + +/** + * Target destination family (D08/D15). `type` names the environment class; `name` the concrete + * ecosystem identity (e.g. harness + claude-code). `custom` covers internal/bespoke frameworks — + * a normal target with path/doc references, not a schema extension (F02). + */ +export const TargetType = { + Harness: "harness", + Framework: "framework", + Platform: "platform", + Custom: "custom", +} as const; +export type TargetTypeValue = (typeof TargetType)[keyof typeof TargetType]; + +/** + * Generated artifact shape (supersedes the prior `medium` term, FU-69). Drives the Builder gate: + * `markdown` → harness agent/skill files; `code` → source (may add implementation.*); + * `platform-config` → managed-platform declarative config. + */ +export const ArtifactFormat = { + Markdown: "markdown", + Code: "code", + PlatformConfig: "platform-config", +} as const; +export type ArtifactFormatValue = (typeof ArtifactFormat)[keyof typeof ArtifactFormat]; + +/** + * The ADL lifecycle stages in loop order (spec → build → evaluate → diagnose → optimize → ship). + * Used ONLY by the INTERNAL `status` profile (below) to record where a subject card currently sits + * in the loop. It is NOT part of the public portable contract — a published card carries no + * lifecycle position. `ship` (⑥ SHIP) was admitted in the #1202 coordinated frozen-contract pass so + * a `ship:PASS` / `ship:FAIL` loop-position stamp validates (ship PRD §8). This enum intentionally + * omits `audit` (a routing sibling, not a loop-order stage). + */ +export const AdlStage = { + Spec: "spec", + Build: "build", + Evaluate: "evaluate", + Diagnose: "diagnose", + Optimize: "optimize", + Ship: "ship", +} as const; +export type AdlStageValue = (typeof AdlStage)[keyof typeof AdlStage]; + +// ── Helpers ──────────────────────────────────────────────────────────────────── + +/** A closed object — undeclared fields rejected (F02 fully-closed core). */ +function closed[0]>(props: T) { + return Type.Object(props, { additionalProperties: false }); +} +/** A non-empty string (identity / description fields must carry content). */ +const Str = () => Type.String({ minLength: 1 }); +/** An array of non-empty strings. */ +const StrArray = () => Type.Array(Str()); +/** A closed literal-union from a const enum object's values (fail-loud on any unlisted value). */ +function enumUnion(values: readonly string[]) { + return Type.Union(values.map((v) => Type.Literal(v))); +} +const BINDING_KIND = enumUnion(Object.values(BindingKind)); +const EXECUTOR_KIND = enumUnion(Object.values(ExecutorKind)); + +// ── ENVELOPE: metadata ──────────────────────────────────────────────────────── + +/** One coherent card identity (distinct from apiVersion and from any package release version). */ +export const MetadataSchema = closed({ + id: Str(), + name: Str(), + version: Str(), + description: Str(), +}); +export type Metadata = Static; + +// ── spec.intent (requirements-first) ──────────────────────────────────────────── + +/** + * A long-form Standard Operating Procedure entry — the fuller procedural intent that PRECEDES the + * derived `jobs[]` slices. `onFailure` is the safe-failure contract for this procedure. + */ +export const SopEntrySchema = closed({ + id: Str(), + when: Str(), + description: Str(), + onFailure: Type.Optional(Str()), +}); +export type SopEntry = Static; + +/** A derived job-to-be-done — a traceable slice of the SOP (jobs feed requirements/evals/fidelity). */ +export const JobSchema = closed({ + id: Str(), + description: Str(), + expectedOutput: Str(), +}); +export type Job = Static; + +/** + * Requirements-first Intent (before kind/target). The long-form `sop` comes before derived `jobs` + * (requirements-first). `assumptions`/`unknowns` keep unverified beliefs from masquerading as facts + * and force the Builder to stop-or-ask rather than guess. + */ +export const IntentSchema = closed({ + problem: Str(), + outcomes: StrArray(), + sop: Type.Array(SopEntrySchema), + jobs: Type.Array(JobSchema), + constraints: StrArray(), + nonGoals: StrArray(), + assumptions: StrArray(), + unknowns: StrArray(), +}); +export type Intent = Static; + +// ── spec.context[] / spec.actions[] (D16 separate contracts) ───────────────────── + +/** + * The read access for one context item — the binding, allowed read operations, and an optional + * auth/config reference. Access is nested WITH the information it supplies (D16): no separate mode + * axis or cross-list reference is needed. `kind` is a CLOSED binding vocabulary — cli · saas · mcp · + * sdk · host-tool (operator ruling R3, 2026-07-22); an unlisted kind FAILS validation. + */ +export const AccessSchema = closed({ + kind: BINDING_KIND, + ref: Str(), + allowedOperations: StrArray(), + authRef: Type.Optional(Str()), +}); +export type Access = Static; + +/** An inbound information requirement + the forms it can take + how it is read (D16). */ +export const ContextSchema = closed({ + id: Str(), + description: Str(), + modalities: StrArray(), + source: Str(), + freshness: Type.Optional(Str()), + sensitivity: Type.Optional(Str()), + access: AccessSchema, +}); +export type ContextItem = Static; + +/** The connector binding for an outbound action. `kind` is the CLOSED binding vocabulary (R3). */ +export const BindingSchema = closed({ + kind: BINDING_KIND, + ref: Str(), + authRef: Type.Optional(Str()), +}); +export type Binding = Static; + +/** Human-gate policy for an outbound action (makes side-effect control testable). */ +export const ApprovalSchema = closed({ + policy: Str(), + when: Str(), +}); +export type Approval = Static; + +/** + * An outbound side-effect requirement (D16) — kept SEPARATE from context reads. `allowedOperations` + * bounds a broad connector to specific writes; `approval`/`evidence`/`onFailure` make the effect + * gated, auditable, and safe on failure. + */ +export const ActionSchema = closed({ + id: Str(), + description: Str(), + binding: BindingSchema, + allowedOperations: StrArray(), + approval: ApprovalSchema, + evidence: Str(), + onFailure: Str(), +}); +export type ActionItem = Static; + +// ── spec.capabilities (requirements before target selection) ───────────────────── + +/** A local/generated code capability the subject needs (each target later proves a binding). */ +export const CodeCapabilitySchema = closed({ + id: Str(), + description: Str(), + constraints: Type.Optional(closed({ sandbox: Type.Boolean() })), +}); +export type CodeCapability = Static; + +/** + * Local capability requirements (curated from the 0.2 tool buckets). `skills` are loadable + * capability refs; `delegates` are downward-dispatch member/agent ids. These are REQUIREMENTS + * declared before any target is chosen; a target later proves a native binding or reports a gap. + */ +export const CapabilitiesSchema = closed({ + code: Type.Array(CodeCapabilitySchema), + skills: StrArray(), + delegates: StrArray(), +}); +export type Capabilities = Static; + +// ── Canonical Workflow graph (one dialect: top-level, embedded, referenced) ────── + +/** + * A node executor binding — the STRICT typed reference `{ kind, ref }` (F03 LOCKED; operator ruling + * R4, 2026-07-22). `kind` is the closed executor vocabulary; `ref` is the id it invokes: + * { kind: member, ref: } — dispatch a multiAgent.members[] member + * { kind: action, ref: } — invoke a spec.actions[] side effect + * { kind: agent|skill, ref: } — invoke an Agent/Skill capability + * { kind: integration|code, ref: } — invoke an integration / code operation + * Required INPUT (context reads) is NOT an executor form — it lives on the node as `contextRefs`. + * The provisional 0.3-draft forms (`actionRef` / `memberRef` / `contextRefs`-inside-executor) are + * REMOVED; the closed object rejects them. The semantic validator resolves action/member refs. + */ +export const ExecutorSchema = closed({ + kind: EXECUTOR_KIND, + ref: Str(), +}); +export type Executor = Static; + +/** + * A returning/branching edge's termination contract (N02). Any edge that can revisit a node must + * declare an enforceable bound — `maxIterations` and/or `exitWhen`. The semantic validator rejects + * an unbounded cycle; the structural schema only shapes the field. + */ +export const LoopSchema = closed({ + maxIterations: Type.Optional(Type.Integer({ minimum: 1 })), + exitWhen: Type.Optional(Str()), +}); +export type Loop = Static; + +/** One outgoing control-flow edge owned by a node. */ +export const EdgeSchema = closed({ + to: Str(), + condition: Type.Optional(Str()), + loop: Type.Optional(LoopSchema), +}); +export type Edge = Static; + +/** + * A workflow step. Verbose `description` is normative (a bare id is insufficient for a Builder). + * `executor` is the STRICT typed {kind, ref} invocation (F03/R4); `contextRefs` is the SEPARATE + * required-input contract (context reads are not an executor form) resolving to spec.context ids. + */ +export const NodeSchema = closed({ + id: Str(), + description: Str(), + executor: Type.Optional(ExecutorSchema), + contextRefs: Type.Optional(StrArray()), + edges: Type.Optional(Type.Array(EdgeSchema)), + terminal: Type.Optional(Type.Boolean()), +}); +export type Node = Static; + +/** The canonical Workflow graph body — one schema for standalone AND embedded graphs. */ +export const WorkflowBodySchema = closed({ + state: Str(), + entry: Str(), + nodes: Type.Array(NodeSchema), +}); +export type WorkflowBody = Static; + +/** An optional embedded-or-referenced workflow (Agent / MultiAgent bodies): inline graph OR a ref. */ +export const WorkflowSlotSchema = closed({ + inline: Type.Optional(WorkflowBodySchema), + ref: Type.Optional(Str()), +}); +export type WorkflowSlot = Static; + +// ── spec.agent (one autonomous subject) ────────────────────────────────────────── + +/** Operative identity, tone, boundaries, stance — verbose YAML data (Agent-only). */ +export const PersonaSchema = closed({ + role: Str(), + description: Str(), +}); +export type Persona = Static; + +/** How an Agent is activated — an inbound event source (Agent-only). */ +export const TriggerSchema = closed({ + id: Str(), + description: Str(), + kind: Type.Union([ + Type.Literal(TriggerKind.A2a), + Type.Literal(TriggerKind.Webhook), + Type.Literal(TriggerKind.Schedule), + Type.Literal(TriggerKind.Queue), + Type.Literal(TriggerKind.Event), + Type.Literal(TriggerKind.Mcp), + Type.Literal(TriggerKind.Manual), + ]), +}); +export type Trigger = Static; + +/** + * The Agent design body — how one autonomous subject realizes the shared intent. `systemPrompt` is + * the ACTUAL runtime prompt (sacred text carried verbatim, not a summary). An Agent may carry an + * optional canonical Workflow (same contract as kind: Workflow) instead of a bespoke decision graph. + */ +export const AgentBodySchema = closed({ + persona: PersonaSchema, + systemPrompt: Str(), + operatingType: Type.Union([ + Type.Literal(OperatingType.Conversational), + Type.Literal(OperatingType.Automation), + Type.Literal(OperatingType.Orchestrator), + ]), + triggers: Type.Optional(Type.Array(TriggerSchema)), + workflow: Type.Optional(WorkflowSlotSchema), +}); +export type AgentBody = Static; + +// ── spec.skill (a loadable capability, not an Agent with a label) ──────────────── + +/** A named input a Skill expects. */ +export const SkillInputSchema = closed({ + name: Str(), + description: Str(), + required: Type.Optional(Type.Boolean()), +}); +export type SkillInput = Static; + +/** A named output a Skill renders. */ +export const SkillOutputSchema = closed({ + name: Str(), + description: Str(), +}); +export type SkillOutput = Static; + +/** A reference/script/asset the Skill bundles (supports progressive disclosure + packaging checks). */ +export const SkillResourceSchema = closed({ + id: Str(), + kind: Str(), + path: Str(), + description: Str(), +}); +export type SkillResource = Static; + +/** + * The Skill design body — host-loadable capability semantics, deliberately NOT Agent anatomy. + * `invocation` replaces Agent inbound-trigger assumptions with host-aware activation; + * `hostRequirements` names the context/action ids the host must provide (declares needs without + * pretending to own the host's connectors); `failureBehavior` prevents silent partial execution. + */ +export const SkillBodySchema = closed({ + purpose: Str(), + invocation: Str(), + instructions: Str(), + inputs: Type.Array(SkillInputSchema), + outputs: Type.Array(SkillOutputSchema), + resources: Type.Array(SkillResourceSchema), + hostRequirements: StrArray(), + failureBehavior: Str(), + progressiveDisclosure: Type.Boolean(), + subagents: Type.Optional(StrArray()), +}); +export type SkillBody = Static; + +// ── spec.multiAgent (envelope + embedded members + wiring) ─────────────────────── + +/** + * An embedded member spec. A member reuses the parent's shared intent/context/actions by REFERENCE + * (`intentRef` / `contextRefs` / `actionRefs`) OR carries its own — either way it is a complete + * Agent/Skill card with its own design body. The reference graph across members must be finite and + * acyclic (N02) — enforced by the semantic validator. + */ +export const MemberSpecSchema = closed({ + intentRef: Type.Optional(Str()), + contextRefs: Type.Optional(StrArray()), + actionRefs: Type.Optional(StrArray()), + intent: Type.Optional(IntentSchema), + context: Type.Optional(Type.Array(ContextSchema)), + actions: Type.Optional(Type.Array(ActionSchema)), + capabilities: Type.Optional(CapabilitiesSchema), + agent: Type.Optional(AgentBodySchema), + skill: Type.Optional(SkillBodySchema), +}); +export type MemberSpec = Static; + +/** An inline embedded member resource card (same envelope; kind restricted to Agent|Skill). */ +export const MemberCardSchema = closed({ + apiVersion: Type.Literal(AGENTSPEC_API_VERSION), + kind: Type.Union([Type.Literal(Kind.Agent), Type.Literal(Kind.Skill)]), + metadata: MetadataSchema, + spec: MemberSpecSchema, +}); +export type MemberCard = Static; + +/** A member entry — an inline embedded card OR a reference to a complete sibling card (N02). */ +export const MemberEntrySchema = Type.Union([ + MemberCardSchema, + closed({ specRef: Str() }), +]); +export type MemberEntry = Static; + +/** + * Member wiring, kept SEPARATE from control flow. `subagents` = dispatch relation (a member an + * orchestrator dispatches downward); `observes` = watch relation (a watchdog monitors without + * dispatching). Keeping them distinct is what makes governance/watch testable apart from delegation. + */ +export const RelationsSchema = closed({ + subagents: Type.Record(Type.String(), StrArray()), + observes: Type.Record(Type.String(), StrArray()), +}); +export type Relations = Static; + +/** The MultiAgent design body — one root orchestrator, embedded members, wiring, and a graph. */ +export const MultiAgentBodySchema = closed({ + orchestrator: Str(), + members: Type.Array(MemberEntrySchema), + relations: RelationsSchema, + workflow: WorkflowSlotSchema, +}); +export type MultiAgentBody = Static; + +// ── spec.targets[] (one vocabulary, multiple destinations) ─────────────────────── + +/** The generated artifact shape + destination path. `format` supersedes the prior `medium`. */ +export const ArtifactSchema = closed({ + format: Type.Union([ + Type.Literal(ArtifactFormat.Markdown), + Type.Literal(ArtifactFormat.Code), + Type.Literal(ArtifactFormat.PlatformConfig), + ]), + path: Str(), +}); +export type Artifact = Static; + +/** Purpose-labeled authoritative guidance for a destination (lets the Builder learn conventions). */ +export const DocumentationSchema = closed({ + purpose: Str(), + url: Str(), +}); +export type Documentation = Static; + +/** Optional generated-code constraints — code targets ONLY (N04). Omitted for markdown/platform. */ +export const ImplementationSchema = closed({ + language: Str(), + toolchain: Str(), +}); +export type Implementation = Static; + +/** + * A supported destination + its generated-artifact contract (D08/D14/D15/N04). `type`/`name` + * identify the environment; `artifact` identifies output; `implementation` (code only) adds + * source-generation constraints; `documentation` teaches custom/internal conventions without a + * schema extension; `capabilityFit` records how the target satisfies required behavior. + */ +export const TargetSchema = closed({ + id: Str(), + type: Type.Union([ + Type.Literal(TargetType.Harness), + Type.Literal(TargetType.Framework), + Type.Literal(TargetType.Platform), + Type.Literal(TargetType.Custom), + ]), + name: Str(), + artifact: ArtifactSchema, + implementation: Type.Optional(ImplementationSchema), + capabilityFit: Str(), + documentation: Type.Array(DocumentationSchema), +}); +export type Target = Static; + +// ── spec.evaluation (universal closure; dataset-local categories, D18/D19) ─────── + +/** A binary, actionable pass/fail claim (every kind closes with measurable correctness). */ +export const CriterionSchema = closed({ + id: Str(), + description: Str(), + type: Type.Union([ + Type.Literal(EvalType.LlmJudge), + Type.Literal(EvalType.CodeCheck), + ]), + goal: Str(), +}); +export type Criterion = Static; + +/** A broad behavior/use-case contract; every dataset item references one scenario directly. */ +export const ScenarioSchema = closed({ + id: Str(), + description: Str(), + expectedBehavior: Str(), + edgeCase: Type.Optional(Type.Boolean()), +}); +export type Scenario = Static; + +/** Direct mapping of a dataset back to Intent jobs, scenarios, and criteria (traceability). */ +export const DatasetMapsToSchema = closed({ + jobs: Type.Optional(StrArray()), + scenarios: Type.Optional(StrArray()), + criteria: Type.Optional(StrArray()), +}); +export type DatasetMapsTo = Static; + +/** + * A dataset-LOCAL semantic slice (D18) — kept next to the dataset it shapes (no separate global + * category layer). `generationGuidance` steers an LLM toward representative, non-repetitive + * construction; `requiredCases` optionally pins combinations that must appear. + */ +export const DatasetCategorySchema = closed({ + id: Str(), + description: Str(), + generationGuidance: Type.Optional(Str()), + requiredCases: Type.Optional(Type.Array(Type.Record(Type.String(), Type.String()))), +}); +export type DatasetCategory = Static; + +/** One dataset-specific case dimension + its allowed values (models an independent variation axis, D18). */ +export const CaseDimensionSchema = closed({ + description: Str(), + values: StrArray(), +}); +export type CaseDimension = Static; + +/** + * One dataset item (D18) — auditable row by row. `case` classifies the item along the dataset's + * `caseDimensions`. `input`/`expected` carry kind-specific payloads (Agent response/actionCalls, + * Skill outputs/hostActions, MultiAgent member/node outputs, Workflow path/nodeOutputs). Those + * payloads are opaque YAML DATA (downstream LLMs/agents read them), so they are not sub-schema'd — + * but the item envelope itself is closed. + */ +export const DatasetItemSchema = closed({ + id: Str(), + category: Type.Optional(Str()), + scenarioRef: Str(), + case: Type.Optional(Type.Record(Type.String(), Type.Unknown())), + input: Type.Optional(Type.Unknown()), + expected: Type.Optional(Type.Unknown()), +}); +export type DatasetItem = Static; + +/** + * One planned or materialized evaluation collection (D18/D19). Items may be inline (`items`) OR a + * manifest pointer (`itemsRef`) using the same row contract — so construction stays auditable + * without forcing thousands of rows into the card. Several datasets can cover different slices. + */ +export const DatasetSchema = closed({ + id: Str(), + description: Str(), + mapsTo: DatasetMapsToSchema, + categories: Type.Array(DatasetCategorySchema), + caseDimensions: Type.Optional(Type.Record(Type.String(), CaseDimensionSchema)), + items: Type.Optional(Type.Array(DatasetItemSchema)), + itemsRef: Type.Optional(Str()), +}); +export type Dataset = Static; + +/** + * The universal evaluation contract — closes EVERY kind with "is it right?" (F05: arrays may remain + * draft/empty during the interview; the approved spec still shows missing links honestly). + */ +export const EvaluationSchema = closed({ + criteria: Type.Array(CriterionSchema), + scenarios: Type.Array(ScenarioSchema), + datasets: Type.Array(DatasetSchema), +}); +export type Evaluation = Static; + +// ── spec (the discriminated resource spec) ─────────────────────────────────────── + +/** + * The resource spec. The kind-native body is one of `agent`/`skill`/`multiAgent`/`workflow`; all + * four are structurally OPTIONAL here and the semantic validator enforces "exactly the one matching + * `kind`, no leakage" (the kind-leakage exit check) — this yields a precise semantic error rather + * than an opaque union mismatch. + */ +export const SpecSchema = closed({ + intent: IntentSchema, + context: Type.Array(ContextSchema), + actions: Type.Array(ActionSchema), + capabilities: CapabilitiesSchema, + agent: Type.Optional(AgentBodySchema), + skill: Type.Optional(SkillBodySchema), + multiAgent: Type.Optional(MultiAgentBodySchema), + workflow: Type.Optional(WorkflowBodySchema), + targets: Type.Array(TargetSchema), + evaluation: EvaluationSchema, + decisionsRef: Type.Optional(Str()), +}); +export type Spec = Static; + +// ── ROOT ────────────────────────────────────────────────────────────────────────── + +/** Shared root props — the ONE envelope, reused by the public schema and the internal profile below. */ +const agentSpecRootProps = { + apiVersion: Type.Literal(AGENTSPEC_API_VERSION), + kind: Type.Union([ + Type.Literal(Kind.Agent), + Type.Literal(Kind.Skill), + Type.Literal(Kind.MultiAgent), + Type.Literal(Kind.Workflow), + ]), + metadata: MetadataSchema, + spec: SpecSchema, +} as const; + +/** + * The full PUBLIC AgentSpec 0.3.0 resource card. Closed envelope — undeclared top-level fields are + * rejected. In particular it carries NO `status` field: a status-bearing card FAILS public validation + * as an unknown field (the internal-status-on-public negative fixture). This is the portable contract. + */ +export const AgentSpecSchema = closed(agentSpecRootProps); +export type AgentSpec = Static; + +// ── INTERNAL PROFILE: top-level `status` (dev-internal only — stripped on publish) ── + +/** + * The ADL loop-state stamp — a CONTROLLED EXTENSION of the same contract, NOT a forked second schema. + * It is a CLOSED object of EXACTLY three fields; a fourth key fails. + * adl_stage — where the subject currently sits in the ADL loop (closed AdlStage enum). + * updated_at — ISO-8601 UTC instant the stamp was last written (pattern-checked). + * last_verdict — the most recent stage verdict, STAGE-QUALIFIED as ":" + * (e.g. "evaluate:PASS"). Stage-qualified — not a bare "PASS" — was chosen so the + * orchestrator build-index (loop position) and check-sync-spec (freshness) can read + * WHICH stage produced the verdict without a second lookup. (operator ruling 2026-07-23) + * + * WHY it exists (operator rulings 2026-07-22 / 2026-07-23): it SUPERSEDES the 0.2 principle that + * "the spec IS the subject record / there is no external registry" for INTERNAL loop tracking only — + * a card gains a private, self-contained loop-state stamp. It never ships: `sanitizeForPublish` strips + * it, and public validation rejects it. + */ +const ADL_STAGE = enumUnion(Object.values(AdlStage)); +/** ISO-8601 UTC instant, e.g. 2026-07-23T12:00:00Z (documented convention; pattern-enforced). */ +const IsoUtcInstant = () => + Type.String({ pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$" }); + +/** + * STAGE-QUALIFIED verdict, ":" (e.g. "evaluate:PASS"). ENFORCED (not just documented): + * the stage prefix MUST be an AdlStage value and the verdict MUST be UPPERCASE. A bare/unqualified + * verdict ("PASS") FAILS — the downstream consumers (build-index loop position, check-sync-spec) parse + * the stage prefix, so an unqualified verdict is a contract violation, not a stylistic nit. The prefix + * alternation is built from AdlStage (single source of truth) so the enum and the pattern never drift. + */ +const StageQualifiedVerdict = () => + Type.String({ pattern: `^(${Object.values(AdlStage).join("|")}):[A-Z][A-Z_]*$` }); + +export const StatusSchema = closed({ + adl_stage: ADL_STAGE, + updated_at: IsoUtcInstant(), + last_verdict: StageQualifiedVerdict(), +}); +export type Status = Static; + +/** + * The INTERNAL profile = the public root + an OPTIONAL top-level `status`, built from the SAME + * `agentSpecRootProps` (a controlled superset, one contract file — never a divergent second schema). + */ +export const AgentSpecInternalSchema = closed({ + ...agentSpecRootProps, + status: Type.Optional(StatusSchema), +}); +export type AgentSpecInternal = Static; + +/** The internal-only top-level fields the SYNC-SOP sanitizer removes before a card is published. */ +export const INTERNAL_ONLY_TOP_LEVEL_FIELDS = ["status"] as const; + +/** + * SYNC-SOP sanitization (F02-safe publish): strip every INTERNAL-only field so a card is safe to + * publish. Today that is exactly the top-level `status` stamp. Returns a NEW object (never mutates the + * input) plus the list of stripped keys for audit / mechanical proof. The returned card validates + * under the PUBLIC `AgentSpecSchema`. Pure; safe on any input (non-objects pass through unchanged). + */ +export function sanitizeForPublish(card: unknown): { card: unknown; stripped: string[] } { + if (typeof card !== "object" || card === null || Array.isArray(card)) { + return { card, stripped: [] }; + } + const out: Record = { ...(card as Record) }; + const stripped: string[] = []; + for (const key of INTERNAL_ONLY_TOP_LEVEL_FIELDS) { + if (key in out) { + delete out[key]; + stripped.push(key); + } + } + return { card: out, stripped }; +} + +// ── Validation ────────────────────────────────────────────────────────────────── + +export interface ValidationResult { + ok: boolean; + /** Human-readable error strings (path: message), empty when ok. */ + errors: string[]; +} + +// Compiled checker — compiled once at module load (mirrors handover-contract.ts). +const AgentSpecChecker = TypeCompiler.Compile(AgentSpecSchema); + +/** + * Validate an arbitrary value against the AgentSpec 0.3.0 STRUCTURAL contract. + * + * STRUCTURAL floor: the compiled TypeBox checker. Catches missing / wrong-typed / out-of-enum / + * non-frozen-apiVersion fields AND undeclared extra fields (additionalProperties:false — the + * typo / smuggled-block case, F02). It does NOT enforce cross-reference / graph / kind-leakage + * rules — compose it with `semanticValidate` from ../validate/semantic-validator.ts for the full gate. + * + * Pure: no I/O, no clock. Never throws — a non-object input yields ok:false. + */ +export function validateAgentSpec(obj: unknown): ValidationResult { + const errors: string[] = []; + if (!AgentSpecChecker.Check(obj)) { + for (const e of AgentSpecChecker.Errors(obj)) { + errors.push(`${e.path === "" ? "/" : e.path}: ${e.message}`); + } + } + return { ok: errors.length === 0, errors }; +} + +// Compiled INTERNAL-profile checker — accepts an optional top-level `status`; rejects everything else +// the public checker would (undeclared fields, wrong enums, a 4th status key, a malformed timestamp). +const AgentSpecInternalChecker = TypeCompiler.Compile(AgentSpecInternalSchema); + +/** + * Validate a value against the INTERNAL AgentSpec 0.3.0 STRUCTURAL profile — the public envelope plus + * an OPTIONAL top-level `status` stamp. Used by dev-internal tooling (check-sync-spec, orchestrator + * build-index) that reads loop-state; NEVER by the publish path (which uses `validateAgentSpec` and + * would reject `status`). Pure; never throws. + */ +export function validateAgentSpecInternal(obj: unknown): ValidationResult { + const errors: string[] = []; + if (!AgentSpecInternalChecker.Check(obj)) { + for (const e of AgentSpecInternalChecker.Errors(obj)) { + errors.push(`${e.path === "" ? "/" : e.path}: ${e.message}`); + } + } + return { ok: errors.length === 0, errors }; +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/lib/entrypoint.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/lib/entrypoint.ts new file mode 100644 index 00000000..9d509717 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/lib/entrypoint.ts @@ -0,0 +1,41 @@ +/** + * scripts/lib/entrypoint.ts — the portable "am I the entrypoint?" check. + * + * WHY THIS EXISTS: `import.meta.main` is NOT portable. Bun always defines it; Node only + * added it natively in v22.18 / v24.2. Under `scripts/cli/run.sh` tiers 2 and 3 + * (`pnpm exec tsx`, `npx tsx`) on Node < 22.18 — which includes the Node 20 this repo's + * CI pins — `import.meta.main` is `undefined`, so `if (import.meta.main)` is false, the + * CLI body never runs, and the process EXITS 0 HAVING DONE NOTHING. That is how + * `*validate-spec` reported PASS without parsing anything. A gate that reports success + * without checking is worse than one that errors, so every entrypoint guard in this + * package routes through here. + * + * HOW: compare this module's own path to the path the runtime was invoked with + * (`process.argv[1]`). Both sides are realpath'd, so a symlinked skill install — the + * deliberate rapid-iteration dev setup — still matches. Semantics are identical to Bun's + * `import.meta.main`: true only when the module is executed DIRECTLY, false when it is + * imported. Verified on bun, Node 20 + tsx, and Node 22 + tsx. + * + * Usage: if (isEntrypoint(import.meta.url)) { … } + */ +import { realpathSync } from "node:fs"; +import { fileURLToPath } from "node:url"; + +export function isEntrypoint(moduleUrl: string): boolean { + const invoked = process.argv[1]; + if (!invoked) return false; + let self: string; + try { + self = fileURLToPath(moduleUrl); + } catch { + return false; + } + const resolve = (p: string): string => { + try { + return realpathSync(p); + } catch { + return p; + } + }; + return resolve(self) === resolve(invoked); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/setup/detect.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/setup/detect.ts new file mode 100644 index 00000000..13476331 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/setup/detect.ts @@ -0,0 +1,67 @@ +/** + * scripts/setup/detect.ts + * Minimal setup-presence probe used by SKILL.md §0. + * Type A — Pure Script (file reads only — no I/O side effects). + * + * Wave-1 is LEAN: there is no onboarding FSM yet (that is a later wave). "complete" simply means + * the skill is installed — i.e. its SKILL.md resolves from this script's location. The *spec + * interview needs no config file to run; it reads from the operator interactively. So the probe is + * deliberately thin: it confirms the skill tree is intact and reports a stable, JSON-shaped result. + * + * Usage: scripts/cli/run.sh scripts/setup/detect.ts + * exit 0 = skill installed (complete) + * exit 1 = skill tree incomplete (SKILL.md not found from the script location) + */ + +import { existsSync, realpathSync } from "node:fs"; +import { resolve } from "node:path"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +export interface SetupResult { + /** True when the skill tree is intact (SKILL.md resolves) — the Wave-1 completeness bar. */ + complete: boolean; + /** Absolute path the probe checked for SKILL.md (for transparency / debugging). */ + skillMdPath: string; + /** Human-readable note for the dashboard / caller. */ + note: string; +} + +/** + * Resolve this script's directory through any symlink chain (rapid-skill-iteration symlinks are an + * intentional dev pattern), then check for the skill's SKILL.md two levels up: + * scripts/setup/detect.ts -> scripts/setup -> scripts -> /SKILL.md + */ +export function resolveSkillRoot(scriptDir: string): string { + return resolve(scriptDir, "..", ".."); +} + +/** + * Run the presence probe. Pure given `scriptDir` — the caller passes the resolved script dir so the + * function is testable against a temp tree (no import.meta dependency inside the pure core). + */ +export function detectSetup(scriptDir: string): SetupResult { + const skillRoot = resolveSkillRoot(scriptDir); + const skillMdPath = resolve(skillRoot, "SKILL.md"); + const complete = existsSync(skillMdPath); + return { + complete, + skillMdPath, + note: complete + ? "mutagent-agentspec is installed. Run *spec to begin the guided interview." + : "mutagent-agentspec skill tree incomplete — SKILL.md not found. Reinstall: pnpx @mutagent/agentspec init", + }; +} + +// ── CLI entrypoint ──────────────────────────────────────────────────────────── +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + // Realpath-resolve through any symlink chain (cwd-leak / symlink-iteration safety). + const scriptDir = realpathSync( + import.meta.dirname ?? + import.meta.url.replace(/^file:\/\//, "").replace(/\/[^/]+$/, ""), + ); + const result = detectSetup(scriptDir); + process.stdout.write(JSON.stringify(result, null, 2) + "\n"); + process.exit(result.complete ? 0 : 1); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/template/slot-checklist.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/template/slot-checklist.ts new file mode 100644 index 00000000..c2dff9e2 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/template/slot-checklist.ts @@ -0,0 +1,175 @@ +/** + * scripts/template/slot-checklist.ts + * The ENUMERATE-FIRST template-slot checklist (SPEC-1 · PR-025). + * Type A — Pure core (deriveSlotChecklist, no I/O) + a thin guarded CLI. Mirrors validate-spec.ts. + * + * WHY: a `*sync-spec` reverse-generate reads an implementation and reverse-maps it onto the spec in + * one free-reading pass — with NO step that first enumerates the real surface into a checklist, it + * silently captures only a FRACTION of the command / hook / file surface, and the `*validate-spec` + * gate checks field SHAPES only (an incomplete spec passes exactly as cleanly as a complete one). + * This script derives, from the ONE worked template (assets/templates/agentspec.yaml.tpl), the + * canonical set of Definition / Build / Appendix SLOTS a draft must DELIBERATELY fill or mark N/A — + * the completeness scaffold the enumerate-first pass drives off (PR-025). It is NOT a mechanical + * tools↔jobs diff: it emits the template's slot skeleton; the actual fill + the impl→spec cross-verify + * are `ai-architect #sync-spec`'s reasoning. + * + * Usage: scripts/cli/run.sh scripts/template/slot-checklist.ts [template.yaml] [--json] + * exit 0 = the checklist derived → one row per slot (section · cardinality · path), or JSON + * exit 1 = the template could not be read/parsed + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { fileURLToPath } from "node:url"; +import { parse as parseYaml } from "yaml"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +/** + * The `spec.*` sections whose slots a draft must deliberately fill or mark empty (AgentSpec 0.3.0). + * A given card carries exactly ONE kind-native body (agent | skill | multiAgent | workflow); the + * derived checklist reflects whichever sections the worked template actually contains. + */ +const SECTIONS = [ + "intent", + "context", + "actions", + "capabilities", + "agent", + "skill", + "multiAgent", + "workflow", + "targets", + "evaluation", + "decisionsRef", +] as const; +type Section = (typeof SECTIONS)[number]; + +/** One template slot the enumerate-first pass must FILL (from the surface) or mark N/A. */ +export interface SlotEntry { + /** dotted path, e.g. "definition.tools.integration". */ + path: string; + /** the top-level section the slot lives in. */ + section: Section; + /** list = a 0..n array; object = a nested-object leaf; scalar = a single value. */ + cardinality: "list" | "object" | "scalar"; +} + +export interface SlotChecklist { + slots: SlotEntry[]; + sections: Section[]; +} + +/** + * Structural CONTAINER keys nested INSIDE a section that we DESCEND into so their child slots are + * listed individually. Top-level object sections (intent · capabilities · agent | skill | … · + * evaluation) are always walked; this set only governs deeper nesting — `persona` inside an Agent + * body. A key NOT in this set is a leaf slot even when its value is an object (e.g. agent.workflow, + * whose internals are the graph body, not fixed fill-slots). + */ +const CONTAINER_KEYS = new Set(["persona"]); + +function isPlainObject(v: unknown): v is Record { + return typeof v === "object" && v !== null && !Array.isArray(v); +} + +function classify(v: unknown): SlotEntry["cardinality"] { + if (Array.isArray(v)) return "list"; + if (isPlainObject(v)) return "object"; + return "scalar"; +} + +/** + * PURE core. Parse the worked template and walk its `spec.*` sections — descending object sections + * (and nested CONTAINER keys), emitting list/scalar sections as single slots — to derive the + * canonical slot checklist. No I/O; on a parse failure, a non-object root, or a missing `spec` + * returns an empty checklist (the CLI reports it as exit 1). + */ +export function deriveSlotChecklist(templateText: string): SlotChecklist { + let parsed: unknown; + try { + parsed = parseYaml(templateText); + } catch { + return { slots: [], sections: [] }; + } + if (!isPlainObject(parsed)) return { slots: [], sections: [] }; + const spec = parsed.spec; + if (!isPlainObject(spec)) return { slots: [], sections: [] }; + + const slots: SlotEntry[] = []; + const sectionsSeen: Section[] = []; + + const walk = (prefix: string, node: Record, section: Section): void => { + for (const [key, value] of Object.entries(node)) { + const slotPath = `${prefix}.${key}`; + if (isPlainObject(value) && CONTAINER_KEYS.has(key)) { + walk(slotPath, value, section); + } else { + slots.push({ path: slotPath, section, cardinality: classify(value) }); + } + } + }; + + for (const section of SECTIONS) { + const value = spec[section]; + if (value === undefined) continue; + sectionsSeen.push(section); + if (isPlainObject(value)) { + walk(section, value, section); + } else { + // A list section (context · actions · targets) or a scalar section (decisionsRef) is one slot. + slots.push({ path: section, section, cardinality: classify(value) }); + } + } + + return { slots, sections: sectionsSeen }; +} + +// ── CLI ───────────────────────────────────────────────────────────────────────── +function defaultTemplatePath(): string { + // scripts/template/ -> skill root -> assets/templates/agentspec.yaml.tpl + const here = path.dirname(fileURLToPath(import.meta.url)); + return path.resolve(here, "..", "..", "assets", "templates", "agentspec.yaml.tpl"); +} + +function runCli(argv: string[]): number { + const args = argv.slice(2); + const json = args.includes("--json"); + const positional = args.find((a) => !a.startsWith("--")); + const templatePath = positional ? path.resolve(positional) : defaultTemplatePath(); + + let text: string; + try { + text = fs.readFileSync(templatePath, "utf-8"); + } catch (err) { + process.stderr.write(`Error reading template ${templatePath}: ${String(err)}\n`); + return 1; + } + + const checklist = deriveSlotChecklist(text); + if (checklist.slots.length === 0) { + process.stderr.write(`[slot-checklist] FAIL — could not derive slots from ${templatePath}\n`); + return 1; + } + + if (json) { + console.info(JSON.stringify(checklist, null, 2)); + return 0; + } + + console.info( + `[slot-checklist] ${checklist.slots.length} template slots — FILL each from the enumerated surface or mark N/A (PR-025):`, + ); + console.info("section cardinality slot"); + console.info("────────── ─────────── ────────────────────────────────────────"); + for (const s of checklist.slots) { + console.info(`${s.section.padEnd(10)} ${s.cardinality.padEnd(11)} ${s.path}`); + } + return 0; +} + +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + const argv = typeof Bun !== "undefined" ? Bun.argv : process.argv; + process.exit(runCli(argv)); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/semantic-validator.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/semantic-validator.ts new file mode 100644 index 00000000..ee99c0ad --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/semantic-validator.ts @@ -0,0 +1,452 @@ +/** + * scripts/validate/semantic-validator.ts + * The SEMANTIC layer of the AgentSpec 0.3.0 gate — everything the closed TypeBox structure cannot + * express. Type A — Pure Script (a pure `semanticValidate(obj) => { ok, errors[] }`, no I/O). + * + * Runs AFTER the structural checker (scripts/contract/agentspec.schema.ts) passes; it assumes a + * roughly-shaped object but narrows defensively (never throws). It enforces the Wave-1 exit checks: + * + * 1. KIND LEAKAGE — exactly the one body matching `kind` is present; no other kind's body. + * 2. WORKFLOW GRAPHS — entry resolves · edge targets resolve · terminal/edge consistency · + * reachability · BOUNDED loops (any cycle-closing edge declares + * loop.maxIterations or loop.exitWhen — unbounded loops fail, N02). + * 3. EXECUTOR BINDING — every node executor has a form and its actionRef/contextRefs/memberRef resolve. + * 4. MULTI-AGENT — orchestrator resolves · unique member ids · relations resolve · + * member dispatch graph is ACYCLIC (N02) · member ref-fields resolve. + * 5. TARGETS — implementation.* only on artifact.format: code (N04). + * 6. DECISION SIDECAR — decisionsRef is a colocated relative sibling (./name.md), no escape (N03). + * 7. EVALUATION REFS — dataset mapsTo/items resolve to jobs/scenarios/criteria/categories/dimensions. + * + * Every failure is a field-pathed string so a `[validate-spec]` run reads like the structural errors. + */ + +import type { ValidationResult } from "../contract/agentspec.schema.ts"; +import { Kind } from "../contract/agentspec.schema.ts"; + +// ── defensive accessors (never throw on malformed input) ────────────────────────── +type Rec = Record; +const isRec = (v: unknown): v is Rec => + typeof v === "object" && v !== null && !Array.isArray(v); +const asRec = (v: unknown): Rec => (isRec(v) ? v : {}); +const asArr = (v: unknown): unknown[] => (Array.isArray(v) ? v : []); +const asStr = (v: unknown): string | undefined => + typeof v === "string" ? v : undefined; +const ids = (arr: unknown[]): Set => { + const s = new Set(); + for (const el of arr) { + const id = asStr(asRec(el).id); + if (id !== undefined) s.add(id); + } + return s; +}; + +// The four kind → body-key pairings. Exactly one body must be present, matching `kind`. +const BODY_KEYS = ["agent", "skill", "multiAgent", "workflow"] as const; +const KIND_TO_BODY: Record = { + [Kind.Agent]: "agent", + [Kind.Skill]: "skill", + [Kind.MultiAgent]: "multiAgent", + [Kind.Workflow]: "workflow", +}; + +/** + * Validate the SEMANTIC rules of an AgentSpec 0.3.0 card. Pure; never throws. Intended to run after + * `validateAgentSpec` (structural) reports ok — but it narrows defensively so a partially-shaped + * object yields errors rather than an exception. + */ +export function semanticValidate(obj: unknown): ValidationResult { + const errors: string[] = []; + const push = (path: string, msg: string) => errors.push(`${path}: ${msg}`); + + const root = asRec(obj); + const kind = asStr(root.kind); + const spec = asRec(root.spec); + + // ── 1. KIND LEAKAGE ───────────────────────────────────────────────────────────── + if (kind !== undefined && kind in KIND_TO_BODY) { + const expected = KIND_TO_BODY[kind]; + if (spec[expected] === undefined) { + push(`/spec/${expected}`, `kind is ${kind} but the matching body is missing`); + } + for (const key of BODY_KEYS) { + if (key !== expected && spec[key] !== undefined) { + push( + `/spec/${key}`, + `kind leakage — kind is ${kind}; a '${key}' body is not permitted`, + ); + } + } + } + + // Shared reference pools drawn from the universal spec. + const contextIds = ids(asArr(spec.context)); + const actionIds = ids(asArr(spec.actions)); + const jobIds = ids(asArr(asRec(spec.intent).jobs)); + const evaluation = asRec(spec.evaluation); + const scenarioIds = ids(asArr(evaluation.scenarios)); + const criterionIds = ids(asArr(evaluation.criteria)); + + // ── 4. MULTI-AGENT (collect member ids first; needed for executor memberRef) ───── + const memberIds = new Set(); + let hasSpecRefMember = false; + if (spec.multiAgent !== undefined) { + const ma = asRec(spec.multiAgent); + for (const m of asArr(ma.members)) { + const mr = asRec(m); + if (typeof mr.specRef === "string") { + hasSpecRefMember = true; + continue; + } + const id = asStr(asRec(mr.metadata).id); + if (id !== undefined) { + if (memberIds.has(id)) push("/spec/multiAgent/members", `duplicate member id '${id}'`); + memberIds.add(id); + } + } + // Unknown-reference errors only fire when EVERY member is inline (specRef targets are external). + const canResolveMembers = !hasSpecRefMember; + const checkMember = (path: string, id: string) => { + if (canResolveMembers && !memberIds.has(id)) push(path, `unknown member '${id}'`); + }; + + const orchestrator = asStr(ma.orchestrator); + if (orchestrator !== undefined) checkMember("/spec/multiAgent/orchestrator", orchestrator); + + // Member ref-fields (intentRef/contextRefs/actionRefs) resolve against the parent spec. + for (const m of asArr(ma.members)) { + const mr = asRec(m); + if (typeof mr.specRef === "string") continue; + const mid = asStr(asRec(mr.metadata).id) ?? "?"; + const mspec = asRec(mr.spec); + const intentRef = asStr(mspec.intentRef); + if (intentRef !== undefined && !intentRef.startsWith("#spec/")) { + push(`/spec/multiAgent/members[${mid}]/intentRef`, `must be an in-card pointer starting '#spec/' (got '${intentRef}')`); + } + for (const c of asArr(mspec.contextRefs)) { + const cid = asStr(c); + if (cid !== undefined && !contextIds.has(cid)) + push(`/spec/multiAgent/members[${mid}]/contextRefs`, `unknown context '${cid}'`); + } + for (const a of asArr(mspec.actionRefs)) { + const aid = asStr(a); + if (aid !== undefined && !actionIds.has(aid)) + push(`/spec/multiAgent/members[${mid}]/actionRefs`, `unknown action '${aid}'`); + } + } + + // Relations resolve, and the dispatch (subagents) graph is ACYCLIC (N02). + const relations = asRec(ma.relations); + const subagents = asRec(relations.subagents); + const observes = asRec(relations.observes); + const adjacency = new Map(); + for (const [from, tos] of Object.entries(subagents)) { + checkMember("/spec/multiAgent/relations/subagents", from); + const list: string[] = []; + for (const to of asArr(tos)) { + const t = asStr(to); + if (t !== undefined) { + checkMember("/spec/multiAgent/relations/subagents", t); + list.push(t); + } + } + adjacency.set(from, list); + } + for (const [from, tos] of Object.entries(observes)) { + checkMember("/spec/multiAgent/relations/observes", from); + for (const to of asArr(tos)) { + const t = asStr(to); + if (t !== undefined) checkMember("/spec/multiAgent/relations/observes", t); + } + } + const cycle = findCycle(adjacency); + if (cycle) { + push( + "/spec/multiAgent/relations/subagents", + `member dispatch cycle is forbidden (N02): ${cycle.join(" → ")}`, + ); + } + } + + // ── 2 + 3. WORKFLOW GRAPHS + EXECUTOR BINDING (every graph in the card) ────────── + for (const g of collectWorkflows(spec)) { + validateGraph(g.body, g.path, { contextIds, actionIds, memberIds, hasSpecRefMember }, push); + } + + // ── 5. TARGETS: implementation only on code artifacts (N04) ────────────────────── + asArr(spec.targets).forEach((t, i) => { + const tr = asRec(t); + const format = asStr(asRec(tr.artifact).format); + if (tr.implementation !== undefined && format !== "code") { + push( + `/spec/targets[${i}]/implementation`, + `only 'code' artifacts may carry implementation.* (format is '${format ?? "?"}', N04)`, + ); + } + }); + + // ── 6. DECISION SIDECAR: colocated relative sibling, no escape (N03) ───────────── + const decisionsRef = asStr(spec.decisionsRef); + if (decisionsRef !== undefined) { + const bad = + !decisionsRef.startsWith("./") || + decisionsRef.includes("..") || + decisionsRef.slice(2).includes("/") || + !decisionsRef.endsWith(".md"); + if (bad) { + push( + "/spec/decisionsRef", + `must be a colocated relative sibling like './agentspec.decisions.md' — no absolute path, directory escape, or subdirectory (N03) (got '${decisionsRef}')`, + ); + } + } + + // ── 7. EVALUATION REFERENCES ───────────────────────────────────────────────────── + asArr(evaluation.datasets).forEach((d, i) => { + const dr = asRec(d); + const base = `/spec/evaluation/datasets[${i}]`; + const mapsTo = asRec(dr.mapsTo); + for (const j of asArr(mapsTo.jobs)) { + const id = asStr(j); + if (id !== undefined && !jobIds.has(id)) push(`${base}/mapsTo/jobs`, `unknown job '${id}'`); + } + for (const s of asArr(mapsTo.scenarios)) { + const id = asStr(s); + if (id !== undefined && !scenarioIds.has(id)) + push(`${base}/mapsTo/scenarios`, `unknown scenario '${id}'`); + } + for (const c of asArr(mapsTo.criteria)) { + const id = asStr(c); + if (id !== undefined && !criterionIds.has(id)) + push(`${base}/mapsTo/criteria`, `unknown criterion '${id}'`); + } + const categoryIds = ids(asArr(dr.categories)); + const dimensionKeys = new Set(Object.keys(asRec(dr.caseDimensions))); + asArr(dr.items).forEach((it, k) => { + const itr = asRec(it); + const ibase = `${base}/items[${k}]`; + const scenarioRef = asStr(itr.scenarioRef); + if (scenarioRef !== undefined && !scenarioIds.has(scenarioRef)) + push(`${ibase}/scenarioRef`, `unknown scenario '${scenarioRef}'`); + const category = asStr(itr.category); + if (category !== undefined && !categoryIds.has(category)) + push(`${ibase}/category`, `unknown dataset-local category '${category}'`); + if (dimensionKeys.size > 0) { + for (const dim of Object.keys(asRec(itr.case))) { + if (!dimensionKeys.has(dim)) + push(`${ibase}/case`, `unknown case dimension '${dim}' (not in caseDimensions)`); + } + } + }); + }); + + return { ok: errors.length === 0, errors }; +} + +// ── Workflow-graph helpers ──────────────────────────────────────────────────────── + +interface GraphRef { + body: Rec; + path: string; +} +/** Collect every canonical Workflow graph in the card: top-level, Agent-embedded, MultiAgent-embedded. */ +function collectWorkflows(spec: Rec): GraphRef[] { + const out: GraphRef[] = []; + if (isRec(spec.workflow)) out.push({ body: spec.workflow, path: "/spec/workflow" }); + const agentWf = asRec(asRec(spec.agent).workflow).inline; + if (isRec(agentWf)) out.push({ body: agentWf, path: "/spec/agent/workflow/inline" }); + const maWf = asRec(asRec(spec.multiAgent).workflow).inline; + if (isRec(maWf)) out.push({ body: maWf, path: "/spec/multiAgent/workflow/inline" }); + return out; +} + +interface RefPools { + contextIds: Set; + actionIds: Set; + memberIds: Set; + hasSpecRefMember: boolean; +} + +function validateGraph( + body: Rec, + path: string, + pools: RefPools, + push: (path: string, msg: string) => void, +): void { + const nodes = asArr(body.nodes); + const nodeIds = new Set(); + for (const n of nodes) { + const id = asStr(asRec(n).id); + if (id !== undefined) { + if (nodeIds.has(id)) push(`${path}/nodes`, `duplicate node id '${id}'`); + nodeIds.add(id); + } + } + + // entry resolves + const entry = asStr(body.entry); + if (entry !== undefined && !nodeIds.has(entry)) + push(`${path}/entry`, `entry node '${entry}' does not exist`); + + // adjacency + per-node structural rules + const adjacency = new Map(); + for (const n of nodes) { + const nr = asRec(n); + const id = asStr(nr.id); + if (id === undefined) continue; + const edges = asArr(nr.edges); + const terminal = nr.terminal === true; + if (terminal && edges.length > 0) + push(`${path}/nodes[${id}]`, `terminal node must have no outgoing edges`); + if (!terminal && edges.length === 0) + push(`${path}/nodes[${id}]`, `non-terminal node must have at least one outgoing edge (or be marked terminal)`); + + // executor binding resolves — strict { kind, ref } (F03/R4). action/member refs resolve. + if (nr.executor !== undefined) { + const ex = asRec(nr.executor); + const exKind = asStr(ex.kind); + const ref = asStr(ex.ref); + if (exKind === "action" && ref !== undefined && !pools.actionIds.has(ref)) + push(`${path}/nodes[${id}]/executor`, `unknown action '${ref}'`); + if (exKind === "member" && ref !== undefined && !pools.hasSpecRefMember && !pools.memberIds.has(ref)) + push(`${path}/nodes[${id}]/executor`, `unknown member '${ref}'`); + } + // required INPUT (context reads) — a SEPARATE node field, not an executor form (F03/R4). + for (const c of asArr(nr.contextRefs)) { + const cid = asStr(c); + if (cid !== undefined && !pools.contextIds.has(cid)) + push(`${path}/nodes[${id}]/contextRefs`, `unknown context '${cid}'`); + } + + const list: string[] = []; + for (const e of edges) { + const to = asStr(asRec(e).to); + if (to === undefined) continue; + if (!nodeIds.has(to)) push(`${path}/nodes[${id}]/edges`, `edge target '${to}' does not exist`); + else list.push(to); + } + adjacency.set(id, list); + } + + // reachability from entry + if (entry !== undefined && nodeIds.has(entry)) { + const reachable = bfs(entry, adjacency); + for (const id of nodeIds) { + if (!reachable.has(id)) push(`${path}/nodes[${id}]`, `node is unreachable from entry '${entry}'`); + } + } + + // BOUNDED loops: a RETURNING edge is a DFS back edge (u → v where v is an ancestor still on the + // traversal stack). Only that returning edge — not the forward edges of the cycle — must declare a + // loop bound (N02). Reachability-based detection would wrongly flag the forward edge too. + const edgeLoopBounded = new Map(); // "u->v" → has a loop bound + const edgeMap = new Map(); + for (const n of nodes) { + const nr = asRec(n); + const u = asStr(nr.id); + if (u === undefined) continue; + const outs: string[] = []; + for (const e of asArr(nr.edges)) { + const er = asRec(e); + const v = asStr(er.to); + if (v === undefined || !nodeIds.has(v)) continue; + outs.push(v); + const loop = asRec(er.loop); + edgeLoopBounded.set(`${u}->${v}`, loop.maxIterations !== undefined || asStr(loop.exitWhen) !== undefined); + } + edgeMap.set(u, outs); + } + for (const backEdge of findBackEdges(nodeIds, edgeMap)) { + if (!edgeLoopBounded.get(`${backEdge.from}->${backEdge.to}`)) { + push( + `${path}/nodes[${backEdge.from}]/edges`, + `returning edge '${backEdge.from} → ${backEdge.to}' closes a loop and must declare loop.maxIterations or loop.exitWhen (N02: no unbounded loops)`, + ); + } + } +} + +/** BFS reachable set from a start node. */ +function bfs(start: string, adjacency: Map): Set { + const seen = new Set([start]); + const queue = [start]; + while (queue.length > 0) { + const cur = queue.shift() as string; + for (const next of adjacency.get(cur) ?? []) { + if (!seen.has(next)) { + seen.add(next); + queue.push(next); + } + } + } + return seen; +} + +/** + * Find every DFS BACK EDGE — an edge u → v where v is an ancestor of u still on the recursion stack + * (i.e. the edge that closes a cycle). Iterates all nodes as roots so cycles are found regardless of + * reachability from entry. Returns each back edge as { from, to }. + */ +function findBackEdges( + nodeIds: Set, + adjacency: Map, +): Array<{ from: string; to: string }> { + const WHITE = 0, GRAY = 1, BLACK = 2; + const color = new Map(); + for (const id of nodeIds) color.set(id, WHITE); + const back: Array<{ from: string; to: string }> = []; + + const dfs = (node: string): void => { + color.set(node, GRAY); + for (const next of adjacency.get(node) ?? []) { + const c = color.get(next) ?? WHITE; + if (c === GRAY) back.push({ from: node, to: next }); + else if (c === WHITE) dfs(next); + } + color.set(node, BLACK); + }; + + for (const id of nodeIds) { + if (color.get(id) === WHITE) dfs(id); + } + return back; +} + +/** Detect a cycle in a directed graph (DFS with a recursion stack). Returns the cycle path or null. */ +function findCycle(adjacency: Map): string[] | null { + const WHITE = 0, GRAY = 1, BLACK = 2; + const color = new Map(); + const nodes = new Set(); + for (const [from, tos] of adjacency) { + nodes.add(from); + for (const to of tos) nodes.add(to); + } + for (const n of nodes) color.set(n, WHITE); + const stack: string[] = []; + + const dfs = (node: string): string[] | null => { + color.set(node, GRAY); + stack.push(node); + for (const next of adjacency.get(node) ?? []) { + const c = color.get(next) ?? WHITE; + if (c === GRAY) { + const idx = stack.indexOf(next); + return [...stack.slice(idx), next]; + } + if (c === WHITE) { + const found = dfs(next); + if (found) return found; + } + } + color.set(node, BLACK); + stack.pop(); + return null; + }; + + for (const n of nodes) { + if (color.get(n) === WHITE) { + const found = dfs(n); + if (found) return found; + } + } + return null; +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/validate-spec.ts b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/validate-spec.ts new file mode 100644 index 00000000..fdd22557 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-agentspec/scripts/validate/validate-spec.ts @@ -0,0 +1,127 @@ +/** + * scripts/validate/validate-spec.ts + * The *validate-spec gate — full round-trip validation of an agentspec.yaml file (AgentSpec 0.3.0). + * Type A — Pure Script (a pure parse+validate function + a thin guarded CLI). + * + * Usage: scripts/cli/run.sh scripts/validate/validate-spec.ts + * exit 0 = the spec parses + validates against agentspec.mutagent.io/v0.3.0 → "[validate-spec] PASS" + * exit 1 = parse error OR structural/semantic violation (field-pathed errors on stdout) + * + * Two-layer gate: the STRUCTURAL TypeBox checker (`validateAgentSpec`) followed by the SEMANTIC + * validator (`semanticValidate` — kind leakage, workflow graphs, member cycles, bounded loops, + * reference resolution). Semantic runs only when structural passes (semantic assumes a shaped card). + * When the input path is known, the colocated decision-sidecar file's EXISTENCE is also checked (N03). + * + * Mirrors the handover-contract.ts CLI: guarded file read, deterministic (the only input is the + * file argument), `isEntrypoint()` entrypoint (portable across bun/node — D16). Never throws on validation — only on a genuinely + * unreadable file (surfaced as exit 1 with a message). + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { parse as parseYaml } from "yaml"; + +import { validateAgentSpec } from "../contract/agentspec.schema.ts"; +import type { ValidationResult } from "../contract/agentspec.schema.ts"; +import { semanticValidate } from "./semantic-validator.ts"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +export interface SpecValidationOutcome extends ValidationResult { + /** True when the YAML failed to parse (distinct from a schema violation). */ + parseError: boolean; +} + +/** + * Parse a YAML spec STRING and validate it against the AgentSpec 0.3.0 contract (structural then + * semantic). Pure: no I/O. A YAML parse failure is reported as { ok:false, parseError:true } rather + * than thrown, so callers get a uniform outcome shape. Semantic checks run only when the structural + * layer passes — the semantic validator assumes a roughly-shaped card. + */ +export function validateSpecYaml(yamlText: string): SpecValidationOutcome { + let parsed: unknown; + try { + parsed = parseYaml(yamlText); + } catch (err) { + return { + ok: false, + parseError: true, + errors: [`YAML parse error: ${err instanceof Error ? err.message : String(err)}`], + }; + } + const structural = validateAgentSpec(parsed); + if (!structural.ok) return { ...structural, parseError: false }; + const semantic = semanticValidate(parsed); + return { ...semantic, parseError: false }; +} + +/** + * Read a spec file from disk and validate it. Throws ONLY when the file cannot be read; a parse or + * schema failure is returned as a non-ok outcome. When the spec declares a `spec.decisionsRef`, the + * referenced sibling file's EXISTENCE is checked here (the FS-aware half of N03; the path-form half + * lives in the pure semantic validator). + */ +export function validateSpecFile(filePath: string): SpecValidationOutcome { + const resolved = path.resolve(filePath); + const text = fs.readFileSync(resolved, "utf-8"); + const outcome = validateSpecYaml(text); + + // FS-aware N03: a declared decision sidecar must actually exist beside the spec. + let decisionsRef: string | undefined; + try { + const parsed = parseYaml(text) as { spec?: { decisionsRef?: unknown } }; + if (typeof parsed?.spec?.decisionsRef === "string") decisionsRef = parsed.spec.decisionsRef; + } catch { + /* parse error already surfaced by validateSpecYaml */ + } + if (outcome.ok && decisionsRef !== undefined) { + const sidecar = path.resolve(path.dirname(resolved), decisionsRef); + if (!fs.existsSync(sidecar)) { + return { + ok: false, + parseError: false, + errors: [ + `/spec/decisionsRef: referenced decision log '${decisionsRef}' does not exist beside the spec (N03)`, + ], + }; + } + } + return outcome; +} + +// ── CLI ───────────────────────────────────────────────────────────────────────── +function runCli(argv: string[]): number { + const inputPath = argv.slice(2).find((a) => !a.startsWith("--")); + if (inputPath === undefined) { + process.stderr.write( + "Usage: scripts/cli/run.sh scripts/validate/validate-spec.ts \n" + + "Validates a spec against the frozen agentspec.mutagent.io/v0.3.0 contract (structural + semantic).\n" + + "Exit 0 = valid; exit 1 = parse error or structural/semantic violation.\n", + ); + return 1; + } + + let outcome: SpecValidationOutcome; + try { + outcome = validateSpecFile(inputPath); + } catch (err) { + process.stderr.write(`Error reading ${inputPath}: ${String(err)}\n`); + return 1; + } + + if (outcome.ok) { + console.info(`[validate-spec] PASS — ${inputPath} is a valid agentspec.mutagent.io/v0.3.0.`); + return 0; + } + for (const e of outcome.errors) console.info(e); + process.stderr.write( + `[validate-spec] FAIL — ${outcome.errors.length} error(s) in ${inputPath}.\n`, + ); + return 1; +} + +const isMain = + isEntrypoint(import.meta.url); +if (isMain) { + const argv = typeof Bun !== "undefined" ? Bun.argv : process.argv; + process.exit(runCli(argv)); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/SKILL.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/SKILL.md new file mode 100644 index 00000000..57ac20d4 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/SKILL.md @@ -0,0 +1,100 @@ +--- +name: mutagent-builder +description: | + The ADL ② BUILD stage: implements a validated agentspec.yaml into a target framework or harness. + Owns *build + the two agents (ai-engineer Actor · ai-architect Verifier); *build dispatches them + through a TDD + coverage loop. The *sync-spec COMMAND is owned by mutagent-agentspec — builder + provides the ai-architect #sync-spec MODE (the single implementation-reader) that agentspec's + *sync-spec delegates to (Helix-mediated), and that *build reuses build-internally when code drifted + ahead. ai-engineer applies any resulting gated spec writes. +license: Apache-2.0 +compatibility: Designed for Claude Code, Codex, Cursor, OpenCode and similar coding-agent runtimes; works with git, gh CLI, and Bun/pnpm/npm runtimes. +metadata: + author: mutagent + version: "0.1.0-alpha.1" +--- + +# mutagent-builder + +The **ADL ② BUILD** stage. Invoke this skill after `mutagent-agentspec` has emitted and validated an +`agentspec.yaml`. BUILD consumes the Definition, implements it into the chosen target, and hands the +result to EVALUATE. + +## §0 — Setup Detection + +`mutagent-builder` ships the write-capable `ai-engineer` Actor and read-only `ai-architect` Verifier. +The parent session routes `*build` here through Helix; BUILD ownership stays in this package. The +`*sync-spec` COMMAND lives in `mutagent-agentspec` and delegates its code-read to this package's +`ai-architect #sync-spec` mode (Helix-mediated) — builder owns the reader, agentspec owns the command. + +## §0.1 — Star-commands + +| Command | Kind | Owner | Binds | Purpose | +|---|---|---|---|---| +| `*build` | agent-chain | own (full) | `references/workflows/build-protocol.md` + `assets/agents/*` | Implement a schema-valid `agentspec.yaml` into the pinned target framework/harness with TDD + coverage gates. | + +> **`*sync-spec` is NOT a builder command** — `mutagent-agentspec` owns it. Builder provides the +> `ai-architect #sync-spec` MODE (the single implementation-reader): the deterministic freshness probe +> `scripts/sync-spec/check-sync-spec.ts` + `assets/agents/ai-architect.md#sync-spec` (read-only draft) + +> `assets/agents/ai-engineer.md` (gated write). AgentSpec's `*sync-spec` delegates to this mode; `*build` +> reuses it build-internally on drift. Reverse-generate = drift-from-nothing → cold construct + warm +> reconcile are one op. + +### Star-command resolution contract + +When you encounter a `*` token: +1. **RESERVED** — `*` marks a command. NOT prose, NOT a file path, NOT an external shortcut. +2. **RESOLVE** — look up `` in the table above. Not found ⇒ ERROR + ask the operator. +3. **BINDING** — read `Kind` + `Binds`: + - `script` ⇒ call the bound script via `scripts/cli/run.sh`. + - `agent-chain` ⇒ load + run the bound workflow steps in order. + - `hybrid` ⇒ call script(s) for deterministic parts, then use the bound agent contract for judgment/writes. +4. **PRE-GATE** — load any pre-gate references the workflow declares. +5. **EXECUTE** — run the steps in order. Invent nothing. + +## §1 — Triggers + +This skill activates on: +- `mutagent-builder` · `/mutagent-builder` +- `*build` · `build` · `implement the spec` · `build the agent` · `scaffold the agent` + +> `*sync-spec` intents (`spec sync` · `sync the spec` · `code drifted from spec` · …) route to +> `mutagent-agentspec`, which delegates the code-read to this package's `ai-architect #sync-spec`. + +## §2 — Architecture + +```mermaid +flowchart LR + spec["agentspec.yaml validated by SPEC"] --> sync{"ai-architect #sync-spec drift? (build-internal)"} + sync -->|missing-spec or needs-sync| arch["ai-architect #sync-spec reads impl + drafts reconcile plan"] + arch --> engSync["ai-engineer applies spec update under gate"] + sync -->|in-sync| build["*build"] + engSync --> build + build --> eng["ai-engineer implements + TDD + coverage"] + eng --> reviewer["ai-architect independently reviews + coverage"] + reviewer -->|PROCEED| eval["handoff bundle to EVALUATE"] + reviewer -->|STEER| eng + reviewer -->|ABORT| parent["parent escalation"] +``` + +## §3 — Bill of materials + +| Surface | Path | +|---|---| +| Authoritative BUILD protocol | `references/workflows/build-protocol.md` | +| OPTIMIZE handoff contract | `references/workflows/optimize-handoff.md` | +| Operative principles | `references/principles.md` | +| BUILD Actor | `assets/agents/ai-engineer.md` | +| BUILD Verifier / sync-spec analyst | `assets/agents/ai-architect.md` | +| Spec-sync freshness probe | `scripts/sync-spec/check-sync-spec.ts` | +| Build input preflight | `scripts/handoff/validate-build-input.ts` | +| Spec implementation coverage gate | `scripts/verify/spec-impl-coverage.ts` | +| Build report template | `assets/templates/build-report.md.tpl` | + +## §4 — Boundary + +- SPEC emits and validates `agentspec.yaml`; it does not own executable BUILD. +- BUILD owns implementation, drift resync, TDD, and `spec-impl-coverage`. +- EVALUATE judges and may emit EDD change requests. +- DIAGNOSE performs RCA; agentspec-backed implementation remedies return to BUILD. +- BUILD ownership stays in this package and is routed as ADL BUILD. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-architect.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-architect.md new file mode 100644 index 00000000..093fa703 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-architect.md @@ -0,0 +1,383 @@ +--- +name: ai-architect +description: > + Pure subagent reviewer — the *build VERIFIER + the SINGLE implementation-reader. Three modes: + the build-verify path (*preflight → *verdict — Context-Inversion review of the Actor's scaffold for + the *build TDD loop; verdict PROCEED | STEER | ABORT); the *verify-remedy path (the ADL ⑤ OPTIMIZE + applied-remedy rubric — PROCEED | STEER | ABORT on an APPLIED change, not a *build scaffold); and + the *sync-spec reconcile path (read-only: reconcile the def → impl → EVAL triad against a target — cold + CONSTRUCT when no spec, warm RECONCILE on drift, reconciling BOTH the spec leg AND the eval-criteria leg + (eval-suite criteria for agent/skill · code-quality criteria for code), incl. the after-the-fact + backwards-update for a .md/skill impl amend — DISPATCHED by agentspec's *sync-spec via Helix, and reused + build-internally on drift). NEVER writes or edits source — read-only review only. +model: opus # CC-NATIVE pin (dogfood F6) — the field the host actually reads at spawn. +tools: Read, Bash, SendMessage +--- + +# mutagent-builder — AI Architect (*build Verifier) + +ACTIVATION-NOTICE: This file contains your full agent operating guidelines. Read the YAML block below. + +```yaml +class: pure_subagent_reviewer + # The nested `inference:` block below is documentation; THIS is operative. +isolation: worktree + +# Explicit LLM inference pin (model-intent-sacred, PR-003): the review reasoning is delegated to the +# HOST coding-agent runtime. The OPERATIVE pin is the top-level `model:` field above (Claude Code reads +# it at spawn); this block restates it. No silent swap, no context-optimized routing, no fallback. THROW. +inference: + model: claude-opus-4-8 # opus for the review/judgment role; matches the top-level pin (F6) + temperature: 0 # PINNED — deterministic verdicts; never varied + model_overridable: true + pin_rationale: "Verdict quality is the gate's value — opus for the faithfulness/contract judgment; temperature 0 for reproducible verdicts (model-intent-sacred: declare, never silently swap)." + +stage: + position: build-verifier + depends_on: [build-actor] + blocks: [build-ship] + +operation_contract: + inputs: + - name: scaffold + schema: "the Actor's scaffolded implementation (worktree paths)" + required: true + validation: + - condition: "scaffold path missing" + on_invalid: "ABORT — nothing to review" + - name: agentspec + schema: "agentspec.yaml (validated agentspec.v0.2.0)" + required: true + validation: + - condition: "spec missing" + on_invalid: "ABORT — cannot review a scaffold without the spec it implements" + - name: pinned_docs + schema: "appendix.framework_docs[target] roots (the same docs the Actor crawled)" + required: true + outputs: + - artifact_name: verdict + path: "/.mutagent/specs/{spec_id}/build/verdict.md" + schema: "{ verdict: PROCEED|STEER|ABORT, findings[], steer_instructions? }" + +file_access: + reads: + - glob: "/**" + scope: worktree + on_missing: "ABORT — scaffold not found" + - glob: "agentspec.yaml" + scope: spec + on_missing: "ABORT — spec not found" + writes: + - glob: "/.mutagent/specs/{spec_id}/build/verdict.md" + scope: worktree + mode: overwrite + on_collision: "overwrite — idempotent re-emit" + # HARD CONSTRAINT: NO source writes/edits. The verifier reviews; it never mutates the scaffold. + +credentials: + required: false + +failure_modes: + - condition: "a spec-declared code tool is missing from the scaffold (spec-impl-coverage STEER, PR-024)" + action: verdict-STEER + on_exhaustion: "STEER — name the uncovered tool id from the coverage table; a green TDD loop does NOT catch a dropped tool, this gate does" + - condition: "scaffold contradicts the spec's definition (wrong tools / dropped JTBD / altered system_prompt)" + action: verdict-STEER + on_exhaustion: "emit STEER with the specific divergence + the spec line it violates" + - condition: "scaffold builds against an API not in the pinned docs" + action: verdict-STEER + on_exhaustion: "STEER — re-crawl the pinned docs; do not ship against an unpinned/guessed API (PR-002)" + - condition: "model intent silently swapped" + action: verdict-ABORT + on_exhaustion: "ABORT — model intent is sacred (PR-003); a silent swap is a hard stop" + +termination: + - condition: "scaffold faithful to the spec + green TDD loop" + status: success # verdict PROCEED + - condition: "recoverable divergence" + status: partial # verdict STEER (Actor re-runs with instructions) + - condition: "unrecoverable / contract violation" + status: failure # verdict ABORT + - condition: "parent_orchestrator_cancelled" + status: failure + +artifact_namespace: "/.mutagent/specs/{spec_id}/build/" + +commands: + - name: "*preflight" + kind: hybrid + binds: "ai-architect.md#preflight-probes" + purpose: "Run read-only pre-flight probes: does the scaffold's tool inventory / JTBD / system_prompt match the spec? Does the TDD loop pass? No writes." + - name: "*verdict" + kind: hybrid + binds: "ai-architect.md#issue-verdict" + purpose: "Issue PROCEED | STEER | ABORT with grounded findings (each cites a spec line OR a pinned-doc reference). Emit verdict.md. Never edit source." + - name: "*sync-spec" + kind: hybrid + binds: "ai-architect.md#sync-spec" + purpose: "Read-only brownfield drift analysis for the def → impl → EVAL triad: run scripts/sync-spec/check-sync-spec.ts, compare agentspec freshness AND eval-criteria freshness against implementation freshness, derive a draft sync plan for BOTH the spec leg and the eval leg when missing or stale, and hand the gated write step to the right owner (spec → ai-engineer; eval criteria → the evaluator's criteria-maintenance hook, sync-eval-criteria.ts). ALSO the after-the-fact backwards-update reconcile for a .md/skill impl amend (DC-4): the markdown was amended first; you reconcile the derived spec (and its eval leg) AFTER." + - name: "*verify-remedy" + kind: hybrid + binds: "ai-architect.md#verify-remedy" + purpose: "ADL ⑤ OPTIMIZE applied-remedy rubric (read-only). Verify an APPLIED remedy (not a *build scaffold): issue PROCEED | STEER | ABORT on the applied change against the diagnosed failure + the subject's SSoT, then (for a .md/skill impl amend) trigger the after-the-fact #sync-spec backwards-update. Emit remedy-verdict.md. Never edit source." + +# Resolution contract (verbatim) +resolution_contract: | + When you encounter a * token: + 1. RESERVED — `*` marks a command. NOT prose, NOT a file path. Never improvise. + 2. RESOLVE — look up in the `commands:` block. Not found => ERROR + ask. + 3. BINDING — read kind: + binds:: + kind: script => CALL the script. Do NOT re-implement in prose. + kind: agent-chain => load + run the workflow steps in order. + kind: hybrid => call script(s) for deterministic parts, reason for the rest. + 4. PRE-GATE — load any pre_gate.loads:. + 5. EXECUTE — run steps IN ORDER. Invent nothing. + 6. purpose:/impact: explain WHY (not executed). +``` + + +You are the **ai-architect**. You are a Context-Inversion reviewer for the `*build` TDD loop: +you review the Actor's scaffold AGAINST the spec + the pinned docs and issue a verdict. You are +**read-only** — you NEVER write or edit source. Your output is a verdict, not a patch. + +> **Standalone — this is a SHIPPED sub-agent contract.** You are NOT the host/monorepo `architect`. +> You depend on NO host agent (`architect` / `developer` / `general-purpose` / `llm-whisperer`). +> mutagent-builder ships you in its npm tarball. + +## Step 0 — Load the card + the scaffold + the pinned docs + +Read the `agentspec.yaml` (AgentSpec 0.3.0, the SSoT) + `agentspec.decisions.md` when referenced, the +Actor's scaffold, and the same target `documentation[]` the Actor crawled. You judge against the card, +not your own taste. + +## Step 0.5 — PLAN check (read-only · READY | BLOCKED · BEFORE any target write) + +`*plan-check`. This is BUILD phase **B4**. The Actor has written the **frozen PLAN section** of the build +report (goal-based task table) but has **written no target files yet**. You check the PLAN read-only +against `agentspec.yaml` + the selected target's `documentation[]` + repository state, and return exactly +one state: + +- **READY** — every task has a user-observable goal, a verifiable outcome, exact artifacts, a justified + component choice **with a cited doc source**, and a check with an expected result; each build-relevant + requirement (intent SOP + jobs, context/action bindings, the kind-native body, bounded Workflow loops) + is mapped; behavioral-only checks are correctly deferred to EVALUATE. +- **BLOCKED** — name the missing evidence or the operator question. **REFUSE READY** when a task lacks a + concrete outcome, an exact artifact, a justified component choice, or a check/expected result; when a + component choice rests on an uncited framework assumption; or when a selected target cannot realize a + required capability/action boundary (report the gap — it blocks only that target). + +You write NO source and the Actor writes NO target file until you return READY. This is the pre-write gate +that makes "zero writes before READY" enforceable (see the PLAN-only fixture in the build-protocol tests). + +## Step 1 — Pre-flight probes (read-only) + +`*preflight`. Check, without mutating anything: +- **Faithfulness (scripted, PR-024)** — do NOT judge this in prose. RUN the build-faithfulness gate + yourself (Context-Inversion — re-check, never trust the Actor's report): + `scripts/cli/run.sh scripts/verify/spec-impl-coverage.ts `. Every + `definition.tools.code[].id` MUST have an `// @implements ` module + a referencing test. A + `[coverage] STEER` (a tool present in the spec but absent from the scaffold) is a STEER — name the + missing tool id. This is exactly the miss a green TDD loop does NOT catch. THEN also confirm the + `system_prompt` + JTBD set match the spec's `definition` verbatim (an altered prompt is a divergence). +- **Doc-grounding** — is every framework API the scaffold uses present in the pinned docs? An API + the docs don't show is an unpinned/guessed surface (STEER — re-crawl, PR-002). +- **Model intent** — is every declared `model` honored verbatim? A silent swap is an ABORT (PR-003). +- **Runtime fidelity** — was the scaffold built for the pinned `build.runtime` ONLY? A throwaway in + one runtime then redone in another (e.g. bash → Bun) is wasted work — STEER (dogfood F4). +- **Build best-practices** — did the Actor apply the provider best-practices from the crawled docs, + chiefly **prompt-caching** (static `system_prompt` + tool defs + few-shot in cache-eligible + prefixes)? A skipped, documented best-practice is a STEER (dogfood F3). +- **TDD** — is the loop actually green (lint+typecheck+build+test)? "Claimed green / actually red" + is an ABORT. + +## #sync-spec — read-only brownfield drift analysis + +`*sync-spec`. You are the SINGLE implementation-reader. This mode is DISPATCHED by agentspec's +`*sync-spec` command (Helix-mediated HandoverBundle, kind:agent) — AgentSpec owns the entry + the +resulting spec, but never reads code; you do. You are ALSO reused build-internally when `*build` detects +drift mid-loop. You own the read-only analysis when the implementation is brownfield (no spec → +CONSTRUCT) or the target code is newer than `agentspec.yaml` (drift → RECONCILE). Run the deterministic +freshness probe before any draft: + +```bash +scripts/cli/run.sh scripts/sync-spec/check-sync-spec.ts --spec --target [--json] +``` + +If the probe returns `missing-spec` or `needs-sync`, do **NOT** free-read the impl's own prose and +reverse-map whatever you happen to notice in one pass — that silently captures only a FRACTION of the +real surface, and `*validate-spec` checks field SHAPES only, so an incomplete spec (7 of 17 commands, +1 of 11 hooks) passes exactly as cleanly as a complete one. Run these three sub-steps IN ORDER — this +is the enumerate-first + cross-verify discipline (SPEC-1 · PR-025): + +#### 1. ENUMERATE-FIRST — list the real surface, then extract against the template + +**Before** reading the implementation's own description, ENUMERATE the real surface into an explicit +checklist — do not summarise, LIST every one: + +- the actual **CLI commands / entrypoints / handlers** the impl exposes (all of them, not the ones a + README highlights); +- the **hooks** it registers (lifecycle / git / framework / event hooks); +- the **files** that constitute the impl (source modules, config, manifests, prompt files, tests); +- the **tool / MCP / integration registrations**, **context sources**, **sub-agents**, and **inbound + activation triggers** it wires; and its **environment / config surface** (`.env(.example)`, framework + config, package/manifest files). + +Then take the agentspec TEMPLATE slot skeleton as the extraction checklist. AgentSpec derives it +deterministically from the ONE worked template +(`mutagent-agentspec/.claude/skills/mutagent-agentspec/assets/templates/agentspec.yaml.tpl`) via +`scripts/template/slot-checklist.ts` and carries it in the delegation bundle; if it is absent (a +standalone builder run), read that template's Definition/Build/Appendix blocks and use its slots +directly. For **every** template slot, DELIBERATELY resolve it: fill it from the enumerated surface, or +mark it **N/A** with a one-line reason. No slot is resolved silently — a slot left blank without an N/A +note is an incomplete draft, not a finished one. + +#### 2. Reverse-map + draft + +Reverse-map the enumerated surface onto the `agentspec.yaml` Definition + Build + Appendix blocks, +preserving the implementation's operative prompt text VERBATIM when it is discoverable (PR-014). Read +files in full — never guess a Definition field from a filename. + +#### 3. CROSS-VERIFY the draft against the enumerated surface (impl→spec — the direction with no home today) + +Run an LLM cross-verify pass comparing the DRAFTED spec back against the enumerated surface from +sub-step 1. This is the **impl→spec** direction — `scripts/verify/spec-impl-coverage.ts` only ever runs +spec→impl (code tools, at BUILD), so an under-captured surface has no gate today. Tie the comparison to +the agentspec (the enumerated surface + the template slots), NOT a mechanical tools↔jobs diff. Report, +per item, everything **present in the surface but MISSING (or only partially captured) in the draft** — +e.g. the CLI commands, hooks, triggers, or context sources the draft dropped. Surface those omissions +UP FRONT so the operator sees them, rather than discovering them after three later challenges. + +Emit a cited sync plan with: + +- freshness status and reason; +- the **enumerated surface checklist** + each template slot's disposition (filled ↦ its source, or N/A ↦ reason); +- implementation files that justify each inferred Definition field; +- the **cross-verify report** — surface items present but missing/partial in the draft (impl→spec); +- proposed `agentspec.yaml` additions/updates; +- validation risks or unknowns requiring operator confirmation; +- the handoff instruction for `ai-engineer` to apply the spec update under the BUILD gate. + +You do **not** write source or update the spec. `ai-engineer` performs the write step after the gate, +then BUILD continues from the schema-valid synchronized spec. If the probe returns `in-sync`, record +that no sync write is needed and proceed to normal `*build` verification. + +### The EVAL leg — reconcile spec ↔ impl ↔ EVAL, not just spec ↔ impl (W2I5 · KP-003) + +`#sync-spec` is a **THREE-leg** reconcile: **def → impl → eval** must stay in lockstep (PR-011). When an +impl amends (the ⑤ OPTIMIZE loop's ai-engineer, or brownfield drift), the eval criteria that GROUND the +subject's evaluation can go stale exactly as the spec can. The **same deterministic probe** carries the +eval leg: pass the criteria artifact with `--eval-criteria ` (auto-located under +`.mutagent/evaluator/living-suite/` when omitted). The probe reports: + +- `evalStatus` ∈ `not-applicable | missing-eval | in-sync | needs-sync` (mirrors the spec leg); +- `driftedLegs` — the legs to reconcile this pass (`spec`, `eval`, or both). + +**Code detects; you reconcile (Model-B).** The probe is a pure freshness predicate — it flags WHICH legs +drifted; it never decides WHICH criteria changed. That reasoning is yours. When `eval` is in `driftedLegs`, +reconcile the eval leg — and its shape depends on the subject kind (this is why W2I5 was gated behind the +W2I1 code-quality leg): + +- **agent / skill / composite subject** → the eval leg is the **eval-suite criteria** (the evaluator's + discovered / maintained criteria for that subject). Reverse-map the amended impl's behavior/JTBD onto the + criteria: flag which are now stale and which new criterion the change demands. +- **code subject** → the eval leg is the **code-quality criteria** (W2I1's `DEFAULT_CODE_QUALITY_CRITERIA` + / `#mode-judge-code-quality`). Reconcile the same way — flag stale/new quality criteria for the amended code. + +Resolve the leg with the evaluator contract `evalLegForSubjectKind(kind)` +(`mutagent-evaluator/.claude/skills/mutagent-evaluator/scripts/sync-eval-criteria.ts`) and draft the +criteria delta as an `EvalCriteriaReconcileRequest{ subjectId, subjectKind, leg, existing, proposed }`. +Add to the cited sync plan, alongside the spec-leg items: + +- the eval leg's `evalStatus` + which subject-kind leg applies (eval-suite vs code-quality); +- the proposed criteria delta (append the novel, revise a same-id criterion's wording for the amended impl) + — an **upsert**, NEVER a delete: a maintained criteria set only grows/revises, never drops (EV-053); +- the handoff instruction for the **evaluator's criteria-maintenance hook** (`reconcileEvalCriteria`) to + COMPUTE the maintained set from the delta under the gate, and for the evaluator session to PERSIST it + (`persist-eval-criteria.ts` `persistEvalCriteria` → `.mutagent/evaluator/living-suite/.criteria.json`). + The hook COMPUTES the grown criteria as DATA; the persist is the WRITE — and only that write bumps the + artifact's freshness back level with the amended impl. This is criteria MAINTENANCE, not judging — the + evaluator stays judge-only (EV-051); you never mutate the criteria yourself, exactly as you never mutate + the spec. + +The spec-leg write remains `ai-engineer`'s; the eval-leg write is the evaluator's `persistEvalCriteria` +(its `reconcileEvalCriteria` hook only COMPUTES). If the probe returns `in-sync` on BOTH legs, record that no +sync write is needed and proceed to normal `*build` verification. + +**Close with a re-probe (self-heal).** After the gated writes land, RE-RUN `check-sync-spec.ts` a final time +and confirm `driftedLegs` is empty (every drifted leg now `in-sync`). A leg still in `driftedLegs` — most +often `eval` because the criteria persist was skipped or wrote a stale artifact — means the reconcile did NOT +close; surface it so the write is re-run, never record `#sync-spec` complete on a still-drifted leg. + +> **Backwards-update direction (DC-4, ⑤ OPTIMIZE).** For a **markdown-native** subject (a `.md`-agent or +> a skill dir) the impl amend happens FIRST (the markdown IS the impl; ai-engineer `#apply markdown`), +> and you run `#sync-spec` AFTER to reconcile the DERIVED spec to the amended markdown — the reverse of +> the code/platform direction (spec-first → def→impl). Same read-only mechanism, opposite arrow: you +> reverse-map the amended markdown onto the `agentspec.yaml` Definition and hand the gated spec write to +> ai-engineer. You still never mutate the spec yourself. + +## Step 2 — Verdict + +`*verdict`. Issue exactly one of: +- **PROCEED** — scaffold is faithful + doc-grounded + green. Safe to ship. +- **STEER** — recoverable divergence. Emit the specific divergence + the spec line OR pinned-doc + reference it violates + the instruction for the Actor's next pass. The Actor re-runs; you re-review. +- **ABORT** — a contract violation (model intent swapped, claimed-green-but-red, scaffold + fundamentally contradicts the spec). Hard stop; escalate to the parent session. + +Every finding cites EITHER a spec line OR a pinned-doc reference — never an unfounded opinion. Emit +`verdict.md` to the artifact namespace. Do NOT edit the scaffold — that is the Actor's job. + +**Fidelity + loss table (0.3.0 — B7).** The post-build verify produces a field/requirement **fidelity +table** in the build report: for each build-relevant requirement — its implementation site, the +check→observed result, and a disposition (honored / approximated / **unsupported** / weakened / omitted). +Check the emitted target shape against the cited target `documentation[]`. Verify every operator-approved +exception. **Reject UNREPORTED loss** — a requirement silently dropped, approximated, or weakened without +an entry is itself a STEER (or ABORT if it contradicts a locked constraint/non-goal): *silence about loss +is a failure.* Report every plan-to-actual deviation. + +> **NOTE — Wave-2 scope.** This contract is SHIPPED now; the full verify loop is wired with `*build` +> in a later wave (lean by design, PR-007). This wave establishes the read-only-reviewer contract. + +## #verify-remedy — the applied-remedy verify rubric (ADL ⑤ OPTIMIZE) + +`*verify-remedy`. In the optimize loop you verify an **APPLIED remedy** — not a `*build` scaffold. The +optimize loop's S2 VERIFY phase dispatches you AFTER ai-engineer applied a change (worktree-scoped, or +a platform new-rev pre-activation); you issue a verdict that decides whether the turn proceeds to +re-eval (PROCEED), re-builds with instructions (STEER), or halts the turn (ABORT). You are **read-only** +— your output is `remedy-verdict.md`, never a patch. Judge the APPLIED change against the diagnosed +failure + the subject's SSoT, checking, in order: + +1. **Addresses the diagnosis** — does the applied change actually target the diagnosed root-cause + (the RCA remedy locus), not an adjacent symptom? A change that misses the locus is a **STEER** (name + the RCA finding it failed to address). +2. **Faithful to the SSoT + subject-kind (DC-4)** — + - code / platform: the def→impl cascade held (spec amended first, impl follows); a spec-less code + amend that forked the SSoT is an **ABORT**. + - .md-agent / skill: the markdown amend is self-consistent; the after-the-fact `#sync-spec` + backwards-update is queued (not yet an ABORT — reconcile follows). +3. **Non-destructive + gated (OP-PR-003 / DC-1)** — the change went through the shared `mutagent-cli + apply` transport (a diff/dry-run exists), not a bespoke in-place overwrite; no real-world write + happened without the caller's gate. A blind/in-place write is an **ABORT**. +4. **No regression introduced** — for code, the worktree `lint + typecheck` are green (a red gate the + amend introduced is a **STEER**); claimed-green-but-red is an **ABORT**. + - **CODE-TARGET (Wave-2 W2I1).** For a `code`-kind subject in the ⑤ OPTIMIZE loop, this check + EXTENDS to the subject's **OWN test suite**: ai-engineer's code-target TDD inner loop (test-first + → lint → typecheck → build → **test**) must have reached **test-green** on the code subject. A + red/incomplete test suite the amend left behind is a **STEER** (re-build to green); a + **claimed-green-but-actually-red** test suite is an **ABORT** (the hard-gate half of the + code-target BOTH-gate must be TRUSTWORTHY before the evaluator's code-quality verdict is even + sought). You are read-only — you VERIFY the reported test-green against the evidence (re-run or + inspect the loop's build report); you never run the fix yourself. +5. **Scope discipline** — the change touched only what the remedy named; unrelated edits are a **STEER**. + +Verdict: +- **PROCEED** — the applied remedy addresses the diagnosis, is SSoT-faithful, non-destructive + gated, + and introduced no regression. The loop advances to the evaluator re-eval swing. +- **STEER** — recoverable: emit the specific gap + the RCA finding / SSoT line it missed + the + instruction for ai-engineer's next amend. The loop re-builds (S1) with your instructions. +- **ABORT** — a contract violation (forked SSoT, blind/in-place write, claimed-green-but-red). Hard + stop; the loop terminates the turn (terminator `aborted`) and escalates to the parent session. + +Every finding cites the RCA remedy locus OR a spec/markdown line. For a `.md`/skill PROCEED, trigger the +after-the-fact `#sync-spec` **backwards-update** so the derived spec reconciles to the amended markdown +(the reconcile write is ai-engineer's, after the gate — you only draft it). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-engineer.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-engineer.md new file mode 100644 index 00000000..13bb18c7 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/agents/ai-engineer.md @@ -0,0 +1,373 @@ +--- +name: ai-engineer +description: > + Pure subagent executor — the *build ACTOR. Receives a validated agentspec.yaml + a chosen target + (framework or harness). Crawls the pinned Appendix framework docs FRESH (WebFetch) at build time, + plans the target repo hierarchy per framework conventions (dogfood H6), scaffolds the + implementation in the target, and runs a TDD verify loop (test-first → lint → + typecheck → build → test). Emits a scaffolded implementation + a build report. Worktree-isolated. + ALSO the fix ACTOR for the ADL ③ OPTIMIZE / EDD loop (F18): consumes an EddChangeRequest the + evaluator (judge-only) sends over SendMessage, amends the named Agent/AgentSpec target (def→impl + cascade on an `agentspec` target), and replies with a ChangeRequestResponse for re-eval. +model: opus # CC-NATIVE pin (dogfood F6) — the field the host actually reads at spawn. +tools: Read, Write, Bash, Monitor, SendMessage +--- + +# mutagent-builder — AI Engineer (*build Actor) + +ACTIVATION-NOTICE: This file contains your full agent operating guidelines. Read the YAML block below. + +```yaml +class: pure_subagent_executor + # The nested `inference:` block below is documentation; THIS is operative. +isolation: worktree + +# Explicit LLM inference pin (model-intent-sacred, PR-003): the *build implementation reasoning is +# delegated to the HOST coding-agent runtime. The OPERATIVE pin is the top-level `model:` field above +# (Claude Code reads it at spawn); this block restates the intent + temperature. No silent swap, no +# context-optimized routing, no retry-on-failure alternate-model fallback. THROW if unsatisfiable. +inference: + model: claude-opus-4-8 # opus (dogfood F6) — the build Actor runs opus, matching the top-level pin + temperature: 0 # PINNED — deterministic scaffolding; never varied + model_overridable: true # explicit override allowed; default-pinned when omitted + pin_rationale: "Opus for the build Actor (dogfood F6 — reverses the earlier sonnet exception). The top-level `model:` is what CC honors; the nested pin must agree (model-intent-sacred: declare, never silently swap)." + +stage: + position: build-actor + depends_on: [spec-validated] + blocks: [build-verify] + +operation_contract: + inputs: + - name: agentspec + schema: "agentspec.yaml (validated agentspec.v0.2.0)" + # required: true for a *build / code-target amend (spec-FIRST, PR-001). RELAXED for a + # spec-less markdown-native IMPL amend via #apply (DC-4 / OP-PR-004): a .md-agent or + # skill subject IS its own SSoT (the markdown is the impl), so an `impl` amend does NOT + # require a pre-existing spec — ai-architect reconciles the spec AFTER (#sync-spec). A + # platform subject is NOT spec-less: reconstruct the spec FIRST, then proceed spec-first. + required: "conditional — true for build/code; false for a spec-less .md/skill impl amend (DC-4)" + validation: + - condition: "spec fails scripts/validate/validate-spec.ts AND subject-kind ∈ {code, platform}" + on_invalid: "escalate — refuse to build/amend an invalid spec where the spec is load-bearing (the SSoT, PR-001)" + - condition: "no spec exists AND subject-kind ∈ {md-agent, skill} AND apply.kind == markdown" + on_invalid: "ACCEPT — proceed with the impl amend (the markdown IS the impl); ai-architect reconciles the spec after the fact (#sync-spec backwards-update). DC-4." + - name: build_target + schema: "build.target_framework from the spec (framework id OR harness:)" + required: true + validation: + - condition: "target_framework is empty" + on_invalid: "escalate — no target to build into" + - name: pinned_docs + schema: "appendix.framework_docs[target] + references/frameworks/doc-pins.md roots" + required: true + validation: + - condition: "no pinned doc root for the chosen target" + on_invalid: "escalate — cannot build a framework target without its doc pins (PR-002)" + outputs: + - artifact_name: implementation + path: "/" + schema: "scaffolded implementation in the target framework/harness" + - artifact_name: build_report + path: "/.mutagent/specs/{spec_id}/build/report.md" + schema: "TDD-loop results + the spec_id back-reference (PR-013 backwards-only linking)" + +file_access: + reads: + - glob: "agentspec.yaml" + scope: spec + on_missing: "escalate — no spec to build" + - glob: "{pinned framework docs via WebFetch}" + scope: web + on_missing: "escalate — pinned docs must crawl fresh at build time (PR-002)" + writes: + - glob: "/**" + scope: worktree + mode: create-or-overwrite + on_collision: "overwrite within the isolated worktree only" + +credentials: + required: false + +failure_modes: + - condition: "pinned doc crawl fails (network / moved root)" + action: escalate + on_exhaustion: "report the dead pin; do NOT scaffold against a stale local copy" + - condition: "TDD loop cannot reach green after fixes" + action: escalate + on_exhaustion: "emit the partial scaffold + the failing-gate report; never claim green when red" + - condition: "a definition.tools.code[].id has no @implements module + test (coverage STEER, PR-024)" + action: implement-the-missing-tool + on_exhaustion: "the build is NOT done — implement the named tool + its test, re-run *coverage; never claim green while coverage is STEER" + - condition: "model pin cannot be satisfied" + action: escalate + on_exhaustion: "THROW — never silently re-target (PR-003)" + +termination: + - condition: "TDD loop green (lint+typecheck+build+test) AND *coverage PASS on the scaffold (PR-024)" + status: success + - condition: "pinned doc crawl or TDD loop unrecoverable" + status: failure + - condition: "parent_orchestrator_cancelled" + status: failure + +artifact_namespace: "/.mutagent/specs/{spec_id}/build/" + +commands: + - name: "*crawl-docs" + kind: script + binds: "ai-engineer.md#crawl-pinned-docs" + purpose: "WebFetch the pinned Appendix doc roots for the chosen target FRESH at build time (PR-002). Never read a vendored copy." + - name: "*plan-layout" + kind: hybrid + binds: "ai-engineer.md#plan-repo-hierarchy" + purpose: "Plan the target repo hierarchy (directory layout, entry points, config files) per the chosen framework's conventions from the FRESH-crawled docs, BEFORE scaffolding (dogfood H6). Emit the planned tree in the build report; scaffold against it — never lay files out ad-hoc." + - name: "*scaffold" + kind: hybrid + binds: "ai-engineer.md#scaffold-target" + purpose: "Scaffold the implementation in the target framework/harness from the spec's definition, honoring model intent verbatim (PR-003)." + - name: "*tdd-loop" + kind: hybrid + binds: "ai-engineer.md#tdd-loop" + purpose: "Run test-first → lint → typecheck → build → test; classify+fix+repeat until green. Never --no-verify." + - name: "*coverage" + kind: script + binds: "scripts/verify/spec-impl-coverage.ts" + purpose: "Build-faithfulness gate (PR-024): assert every definition.tools.code[].id has an `// @implements ` module + a test. A miss is a build-not-done. Run via scripts/cli/run.sh; green requires THIS pass AND the TDD pass." + - name: "*amend" + kind: agent-chain + binds: "ai-engineer.md#amend-on-edd-request" + purpose: "F18 EDD CLOSURE — consume an EddChangeRequest the evaluator sent over SendMessage (failing cases + grounded refs + remedy target agentspec|impl), amend the NAMED artifact, re-run *build (+ *tdd-loop + *coverage) when the target is `agentspec` (def→impl cascade), and reply with a ChangeRequestResponse {amended|rejected, note}. This is how the Evaluator (judge-only) drives the OPTIMIZE loop without ever patching the subject itself." + - name: "*apply" + kind: hybrid + binds: "ai-engineer.md#apply-modes" + purpose: "ADL ⑤ OPTIMIZE on-ramp (DC-4/DC-5). Produce the amended artifact for the subject-kind, then hand it to the SHARED `mutagent-cli apply` service (never a bespoke writer). #apply MODES keyed by apply.kind: `code-pr` (spec-first amend → shared apply with lint/typecheck) · `markdown` (a spec-less .md-agent OR skill dir impl amend → shared apply, no build) · `cloud-deploy` (reconstruct-spec-first, then amend → shared apply create-rev+activate). The apply-GATE is the CALLER's (optimize loop / diagnose route) — this actor edits + shells the transport, it does not prompt." + +# Resolution contract (verbatim) +resolution_contract: | + When you encounter a * token: + 1. RESERVED — `*` marks a command. NOT prose, NOT a file path. + *command = THIS skill's semantic map (internal). Never improvise. + 2. RESOLVE — look up in the `commands:` block. Not found => ERROR + ask. + 3. BINDING — read kind: + binds:: + kind: script => binds: => CALL the script. Do NOT re-implement in prose. + kind: agent-chain => binds: => load + run the steps in order. + kind: hybrid => binds: both => call script(s) for deterministic parts, reason for the rest. + 4. PRE-GATE — load any pre_gate.loads:. + 5. EXECUTE — run compresses:/workflow steps IN ORDER. Invent nothing. + 6. purpose:/impact: explain WHY (not executed). compresses: MAY reference other *commands (composition). +``` + + +You are the **ai-engineer**. You receive a VALIDATED `agentspec.yaml` and a chosen +target, and you implement the agent the spec describes. You do NOT design (the spec is the +Definition — the SSoT) and you do NOT orchestrate — you execute the build and emit a scaffold + +report. + +> **Standalone — this is a SHIPPED sub-agent contract.** You depend on NO host/monorepo agent +> (`architect` / `developer` / `general-purpose` / `llm-whisperer`). Everything you need is in this +> file and the spec you were handed. mutagent-builder ships you in its npm tarball so a standalone +> `pnpx @mutagent/builder init` environment can dispatch you. + +## Step 0 — Read the card; it is the source of truth (PR-001) + +Read the handed `agentspec.yaml` (AgentSpec 0.3.0) in full, plus the colocated `agentspec.decisions.md` +when `spec.decisionsRef` is set (the pair is one bundle). The `spec` block is the interface you +implement: `intent` (problem · outcomes · long-form `sop` · derived `jobs` · constraints · nonGoals · +assumptions · unknowns — SOP/jobs are shared intent, NOT Agent-only fields), `context[]` (inbound +info + its `access` binding), `actions[]` (bounded outbound effects + approval/evidence/onFailure), +`capabilities` (code · skills · delegates), the ONE kind-native body (`agent`|`skill`|`multiAgent`| +`workflow`), and `evaluation`. You implement INTO the **selected target** — `spec.targets[]` entry by +`id` (REQUIRED to be explicit when the card declares more than one): its `type`/`name`, +`artifact.format`/`path`, `documentation[]`, and — for `format: code` only — `implementation.language`/ +`toolchain`. NEVER mutate the card — the implementation cascades one direction (def → impl). + +## Step 1 — Crawl the selected target's docs FRESH (PR-002) + +`*crawl-docs`. SDKs/conventions churn — never scaffold against a stale local copy. WebFetch each +selected target's `spec.targets[].documentation[]` (load by `purpose`) — and `references/frameworks/ +doc-pins.md` for canonical roots — at build time. A **custom** target is a normal target whose +conventions come from its linked docs. If a doc pin is dead/moved/contradictory, that gap **blocks only +that target** (report it) — do not guess the API. + +## Step 1.5 — PLAN: expand the layout into a complete translation plan — `#plan-repo-hierarchy` + +`*plan-layout`. This is the **PLAN phase (B3)** and it produces the **frozen PLAN section** of the build +report — written BEFORE any target write and checked READY by the architect (B4) before you write a +single file. A file list is NOT a plan. + +1. **Repository hierarchy** — from the conventions crawled FRESH (Step 1) for the selected target, lay + out the directory hierarchy, entry points, and config files the framework expects (e.g. Mastra + `src/mastra/{agents,tools,workflows}` + `index.ts`; `harness:claude-code` `.claude/agents/` + + `CLAUDE.md`). If the target has no canonical layout, state the convention you adopt + why. +2. **Goal-based task grammar** — map **each build-relevant requirement → target primitive/file/test/ + evidence**. Every task carries: a user-observable **goal**, a bounded **task**, the **exact + artifacts** (path/binding), the selected **components/primitives + rationale + doc source**, + dependencies, and one or more **checks with expected results**. Trace every intent SOP + derived job + to the kind-native design → target output → tests → evidence (per the per-kind path in + `build-protocol.md`). Mark behavioral checks that belong to EVALUATE (not run at BUILD). +3. **Freeze + hand to the architect.** Write the PLAN into the report with `Status: BLOCKED` until the + architect returns READY. A task is not READY if success depends only on "looks correct" or an uncited + framework assumption — surface the missing evidence or the operator question instead. **Do NOT write + any target file until the architect marks the PLAN READY (B4).** Then execute the READY plan tests-first + (Step 2) — execute the checked plan, never an improvised structure invented while writing. + +## Step 2 — Scaffold the implementation (PR-003) + +`*scaffold`. Implement the agent in the target framework/harness from the spec's `definition`, for +the runtime pinned in `build.runtime` — build for THAT runtime ONCE; never scaffold a throwaway in +one runtime then redo it in another (dogfood F4). **Package manager by language (dogfood F11):** use +`bun` for JS and `pnpm` for TypeScript projects by default — fall back only if the preferred tool +isn't on the host. **Tool binding is TARGET-CONDITIONAL (PR-004, dogfood F5):** bind per the spec's +strategy for the chosen target — `harness:claude-code`/`harness:codex` → CLI-first (gh/git/cli); +code frameworks (mastra/langgraph/pydantic-ai) → MCP/Composio/SDK in the framework's language. Honor +every declared `model` (and `subagents[].model`) VERBATIM — if the target cannot satisfy a model +constraint, THROW, never silently re-target (model intent is sacred, PR-003). + +## Step 2.5 — Apply provider best-practices (dogfood F3) + +From the docs you crawled FRESH in Step 1, apply the target provider's best-practices to the +scaffold — chiefly **prompt-caching**: place the static `system_prompt` + tool/skill definitions + +any few-shot context in cache-eligible prefixes per the provider's caching guidance, so the built +agent is cost- and latency-efficient. Apply any other documented build hygiene the docs call out +(structured outputs, retries/backoff, batching). Don't guess the caching API — use the crawled docs. + +**Observability sink (dogfood F21):** the scaffolded agent MUST persist its run outputs + traces +(inputs, tool calls, decisions, final output) to a DISCOVERABLE sink — a local file under the +subject's artifact root (e.g. `/traces/`) or a configured trace backend. Without this, +`*eval` (native-matrix judge, F9) and `*diagnose` have no evidence to read. Wire the sink at build +time; surface its path in the build report. Relative paths only — never an absolute path. + +**Emit conformant UniTF via the capture WRAP (F1 — secondary):** when the target is a bare **code +agent** (no obs-platform, no harness), the run has nowhere to source eval/diagnose data from. The +user must NEVER hand-emit UniTF. Instead, SHOULD scaffold the `@mutagent/tools` **`captureUniTF`** +boundary wrap around the agent's run entry (`captureUniTF(runAgent)`) so standalone runs dump a +conformant UniTF `.jsonl` to the sink above — the exact single-intake format `*eval` and `*diagnose` +already read (a source of `platform: local-jsonl` + `format: unitf` then reads it directly). Follow +the know-how GUIDE at `mutagent-tools/references/trace-standardization.md` (how to wrap a code +agent's run · the line contract · where the jsonl lands). This is a WRAP at ONE boundary, NOT +per-function decorators. Secondary/optional: the evaluator's code-run/eval path already applies the +same wrap when it runs the agent — scaffolding it here just lets standalone runs self-emit too. + +## Step 3 — TDD verify loop + +`*tdd-loop`. Test-first → lint → typecheck → build → test; classify failures, fix, REPEAT until +green. NEVER `--no-verify`. The `evals.success_criteria` from the spec seed the acceptance check. + +As you scaffold (Step 2), mark each implementing module with a `// @implements ` comment for +EVERY `definition.tools.code[].id` it realizes, and write ≥1 test that references that module. This is +the contract the faithfulness gate (Step 3.5) checks — do it as you go, not after. + +## Step 3.5 — Build-faithfulness gate (PR-024) — `*coverage` + +`*coverage`. TDD proves the code that EXISTS passes; it is SILENT on whether all the code the SPEC +requires exists (a dropped tool simply has no test to fail). So **a build is GREEN only when the TDD +loop passes AND the coverage gate passes** — both, every time. + +Run `scripts/cli/run.sh scripts/verify/spec-impl-coverage.ts `. It asserts +every `definition.tools.code[].id` has an `// @implements ` module + a referencing test (and that +any `jobs_to_be_done[].backed_by` ref resolves). A `[coverage] STEER` is a build-NOT-done: implement +the named tool + its test, re-run, and only then proceed. Emit the resulting tool-id → module → test +coverage table into the build report. + +Emit the build report to the artifact namespace with the `spec_id` back-reference (the built impl +points UP to the spec, PR-013) — the spec never enumerates the impl. Never claim green while coverage +is STEER. + +## Step 4 — Hand off (+ verbose entity card, dogfood F22) + +Emit the scaffolded implementation + the build report. The `ai-architect` Verifier reviews +your scaffold against the spec + the pinned docs and issues PROCEED | STEER | ABORT before anything +ships. + +Also emit a **verbose entity card** for the operator (dogfood F22) — a compact box summarizing what +this `*build` produced: subject (`spec_id`) · target_framework + runtime · the scaffolded files + +the implemented `tools.code[]` (with the coverage table from Step 3.5) · TDD result · caching applied +y/n · the build-report path. This is the post-stage state the operator tracks (mirrors the entity +cards `*build-dataset`/`*build-evals` emit). Keep it terminal-renderable (box-drawing), not a wall of text. + +## Step 5 — EDD CLOSURE: amend on an evaluator change-request (F18) — `#amend-on-edd-request` + +You are also the **fix ACTOR for the ADL ③ OPTIMIZE / Eval-Driven-Development loop**. The Evaluator is +**judge-only** (EV-051) — it never patches the subject; instead it **REQUESTS** you to amend, over the +`SendMessage` tool you both carry. When you receive an **`EddChangeRequest`** (the contract lives in +the evaluator skill: `schemas/edd-change-request.schema.yaml` + `scripts/edd/edd-types.ts`), do this: + +1. **Read the request.** It carries `swing`, the `subject`, a `remedyTarget ∈ {agentspec, impl}`, the + `failingCases[]` (each with the verbatim `critique` + ≥1 grounding `ref{obs,path,value}`), and a + `proposedRemedy` (a HYPOTHESIS — you decide the actual fix, the evaluator does not mandate it). +2. **Validate + reproduce.** Treat the grounded refs as the evidence. If the failing cases are NOT + reproducible against the current spec/impl, or the `remedyTarget` is wrong (e.g. the request asks + for an `impl` fix but the defect is a DEFINITION gap), **REJECT** — reply with a + `ChangeRequestResponse {status: rejected, note: }`. Never silently amend the wrong + artifact, and never amend without a reproduced defect. +3. **Amend the NAMED artifact — the direction is fixed (def → impl):** + - **`remedyTarget: agentspec`** → edit the **`agentspec.yaml` DEFINITION** (the `system_prompt` / + `sop` / `jobs_to_be_done` / `evals` — whatever the failing cases localize). Then **re-run + `*build`** (→ `*tdd-loop` → `*coverage`) so the def→impl cascade re-scaffolds the implementation. + The spec is the SSoT (PR-001); the impl follows it. Set `rebuilt: true` in the response. + - **`remedyTarget: impl`** → edit the **implementation scaffold ONLY** (a wiring / build-faithfulness + defect that does NOT change the spec — e.g. a `// @implements` tool that mis-handles an input). + Run `*tdd-loop` + `*coverage`. **Never mutate the spec** on an `impl` amend. +4. **Hold the build green.** Every amend re-passes the FULL gate: `*tdd-loop` green AND `*coverage` + PASS — both, every time. **Never `--no-verify`; never claim green while red** (failure_modes hold). +5. **Reply** with a `ChangeRequestResponse {requestId, status: amended, amendedTarget, rebuilt?, note}` + over `SendMessage(to: "evaluator", …)`. The `note` summarizes WHAT you amended (or, on reject, WHY). + The evaluator then **re-evals** what you amended — an amend ALWAYS triggers a fresh eval swing; you + do not self-certify. The loop is BOUNDED on the evaluator side (full-green ⇒ done; or + max-swings/wallclock/no-improvement ⇒ stop) — you simply amend-or-reject each request you receive. + +> **Boundary.** You amend the artifact the spec/impl cascade owns; you do NOT judge, evaluate, or +> decide when the loop terminates (that is the evaluator's `optimize` mode). spec + impl + eval stay in +> **lockstep** (PR-011): the evaluator names the locus, you cascade def→impl, the re-eval re-grounds. + +> **NOTE — Wave-2 scope.** This contract is SHIPPED now; the full build loop (doc-crawl reliability, +> the def→impl cascade mechanism, harness-target emission) is wired in a later wave (lean by design, +> PR-007). This wave establishes the contract + the discipline. + +## Step 6 — `#apply-modes`: the ⑤ OPTIMIZE on-ramp, keyed by subject-kind (DC-4/DC-5) + +`*apply`. You are the WRITE actor for the ⑤ OPTIMIZE stage's apply. You do NOT own an apply +mechanism — you produce the amended artifact and hand it to the **SHARED `mutagent-cli apply` +service** (`@mutagent/tools`), which does the read-before-write → dry-run diff → write → audit for +every transport. **You never prompt for approval** — the apply-GATE is the CALLER's (the optimize +loop or the diagnose route gates the human decision BEFORE it dispatches you; DC-1). + +Three modes, dispatched by `apply.kind`. Each ends by shelling the shared transport +`mutagent-cli apply --kind --target … --dry-run` (preview) then, after the caller's gate, +`--commit`. The revert branch is `mutagent-cli apply --rollback ` — non-destructive. + +1. **`code-pr`** (subject-kind = code · mastra / cloud-agent-sdk) — **spec-FIRST**. The def→impl + cascade is load-bearing: amend the `agentspec.yaml` DEFINITION first (or, if the code drifted + ahead, reconcile via ai-architect `#sync-spec` cold-CONSTRUCT), THEN re-scaffold the impl. Hand the + source edits to `mutagent-cli apply --kind code-pr` (it runs **lint + typecheck** in the worktree → + PR to base main). Never `--no-verify`; never claim green while red. + + > **CODE-TARGET TDD inner loop (Wave-2 W2I1 — the ⑤ OPTIMIZE code-target branch).** When this + > `#apply code-pr` runs INSIDE the ⑤ OPTIMIZE loop for a `code`-kind subject (`--goal + > code-quality`), the apply is not merely lint+typecheck: you run your **full code-target TDD + > inner loop on the code subject** — **test-first → lint → typecheck → build → test** (the same + > `*tdd-loop` discipline, `*coverage` included) — and drive it to green. This is YOUR OWN + > tool-loop: you run it end-to-end as ONE opaque S1 dispatch, you **spawn NO sub-agents**, and + > from the conducting session's view it is a single step (Model-B / PR-ORCH-01: code answers + > gate questions, it never dispatches agents). Report the **hard deterministic result — whether + > the code subject's OWN test suite is green (`testsGreen`)** — back to the loop; that is half of + > the code-target BOTH-gate ("converged" = tests-green AND the evaluator's code-quality verdict). + > Never `--no-verify`; never claim green while red — a red suite is reported red (the loop keeps + > iterating), never smoothed into a pass. + +2. **`markdown`** (subject-kind = .md-agent · harness:claude-code — OR a skill dir) — **backwards-update + (spec-less accepted, DC-4)**. The markdown IS the impl: edit the `.md` frontmatter/sections (an + agent) or the SKILL.md + references + assets (a skill dir; the target root is the DIR). NO + pre-existing spec is required. Hand the edits to `mutagent-cli apply --kind markdown` (the same + worktree-PR transport, **build skipped**). ai-architect reconciles the spec AFTER (`#sync-spec`). + +3. **`cloud-deploy`** (subject-kind = platform · cloud-rest / vendor) — **reconstruct-spec-FIRST**. A + platform agent is opaque: recover an AgentSpec first (ai-architect `#sync-spec` cold-CONSTRUCT from + the platform GET + trace evidence), THEN proceed spec-first like code. Hand the new config to + `mutagent-cli apply --kind cloud-deploy` (non-destructive create-rev + activate, D3). + +> **Boundaries preserved (verbatim).** You never mutate a spec on an `impl`/`markdown` amend; the spec +> reconcile is ai-architect's `#sync-spec` (read-only draft) AFTER, not yours. You never gate the human +> decision — the caller does. You never write outside the shared transport — no bespoke PUT/PR path +> lives here anymore (the retired apply-worker's mechanics are the shared adapters now, DC-5). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/fixtures/plan-only/build-report.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/fixtures/plan-only/build-report.md new file mode 100644 index 00000000..159ab9e2 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/fixtures/plan-only/build-report.md @@ -0,0 +1,54 @@ + +# BUILD Report — support-triage + +| Field | Value | +|---|---| +| Spec | `.mutagent/specs/support-triage/agentspec.yaml` | +| Spec version | `1.0.0` | +| Kind | `Agent` | +| Decision log | `./agentspec.decisions.md` | +| Selected target | `claude-code` — `harness` / `claude-code` | +| Artifact | `markdown` → `.claude/agents/support-triage.md` | +| Code implementation | `n/a` (markdown target — no implementation.*) | +| Target root | `./` | +| Verdict | `PLAN — not yet executed` | + +## PLAN · frozen before target writes + +**Status:** `BLOCKED` — the operator must resolve `intent.unknowns[0]` ("Confidence threshold for +mandatory escalation") before task T2's check has an expected result. No target file is written while +BLOCKED. +**Inputs:** spec + selected target `claude-code` + fresh docs (`agent-format`) + repository snapshot +**Source digest:** `sha256:… (agentspec.yaml @ 1.0.0)` +**Goal:** A `.claude/agents/support-triage.md` harness agent that triages a ticket, cites evidence, and +never performs the `update-ticket` action without recorded approval. + +| Task | Verifiable outcome | Exact artifacts | Components + why / doc source | Check → expected result | +|---|---|---|---|---| +| T1 | The harness agent file carries the sacred `systemPrompt` verbatim + the two context bindings (`ticket-record`, `account-record`). | `.claude/agents/support-triage.md` | Claude Code agent frontmatter + MCP tool bindings (doc: `agent-format`) — the harness binds MCP context reads natively. | `grep` the file for the verbatim systemPrompt + both MCP refs → both present. | +| T2 | The agent escalates instead of acting when confidence is below the mandatory-escalation threshold. | same file (workflow `classify → escalate` branch) | Canonical Workflow inline graph → harness prompt sections. | Run the `ambiguous-evidence` scenario → agent escalates, no `update-ticket`. **Expected result UNRESOLVED** — the threshold is `intent.unknowns[0]`. → **blocks READY**. | +| T3 | `update-ticket` is unreachable without an approval turn. | same file (workflow `propose → apply` gated by approval) | approval-gated action pattern (doc: `agent-format`). | Run the `rejected-update` scenario → no action call. | + +**Build checks:** lint · typecheck · build · tests · coverage · target smoke *(not run — PLAN is BLOCKED)* +**EVALUATE later (not run at BUILD):** the behavioral criteria `no-unapproved-write`, `grounded-route` +and the `triage-golden` dataset scenarios — judged at ③ EVALUATE, not at BUILD. + +## Pinned docs crawled (fresh, by purpose) + +- `agent-format` → `https://example.test/claude-code/agents` (crawled fresh at plan time). + +## Planned hierarchy + +```text +./.claude/agents/ +└── support-triage.md # (planned — NOT YET WRITTEN; blocked pending T2 threshold) +``` + + diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/templates/build-report.md.tpl b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/templates/build-report.md.tpl new file mode 100644 index 00000000..51b5fcfd --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/assets/templates/build-report.md.tpl @@ -0,0 +1,79 @@ +# BUILD Report — {{spec_id}} + +| Field | Value | +|---|---| +| Spec | `{{spec_path}}` | +| Spec version | `{{spec_version}}` | +| Kind | `{{kind}}` | +| Decision log | `{{decisions_ref}}` | +| Selected target | `{{target_id}}` — `{{target_type}}` / `{{target_name}}` | +| Artifact | `{{artifact_format}}` → `{{artifact_path}}` | +| Code implementation | `{{implementation}}` (code targets only) | +| Target root | `{{target_root}}` | +| Verdict | `{{verdict}}` | + + +## PLAN · frozen before target writes + +**Status:** `{{plan_status}}` +**Inputs:** spec + selected target + fresh docs + repository snapshot +**Source digest:** `{{source_digest}}` +**Goal:** {{build_goal}} + +| Task | Verifiable outcome | Exact artifacts | Components + why / doc source | Check → expected result | +|---|---|---|---|---| +| T1 | {{t1_outcome}} | {{t1_artifacts}} | {{t1_components}} | {{t1_check}} | + +**Build checks:** lint · typecheck · build · tests · coverage · target smoke +**EVALUATE later (not run at BUILD):** {{evaluate_deferred}} + +## Pinned docs crawled (fresh, by purpose) + +{{pinned_docs}} + +## Planned hierarchy + +```text +{{planned_tree}} +``` + + +## BUILD RESULT · completed after execution + +### Files changed + +{{files_changed}} + +### TDD gates + +{{tdd_results}} + +### Spec implementation coverage + +{{coverage_table}} + +### Fidelity + loss (silence about loss is a failure) + +| Requirement | Where implemented | Check → observed | Disposition | +|---|---|---|---| +| {{req}} | {{impl_site}} | {{observed}} | honored / approximated / **unsupported** / weakened / omitted (+ reason, operator-approved exception) | + +### Plan-to-actual delta + +{{plan_delta}} + +### Verifier findings + +{{verifier_findings}} + +## EVALUATE handoff bundle + +{{evaluate_handoff}} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/references/principles.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/principles.md new file mode 100644 index 00000000..100714f4 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/principles.md @@ -0,0 +1,18 @@ +# mutagent-builder — Principles (redirect) + +The principle bodies moved to **`.meta/design-principles.md`** on 2026-08-06 and were renumbered from +`PR-BUILD-001..006` to the house `PR-001..006` scheme. The old ids did not match the `.meta/` +toolchain's `PR-` pattern, so the constitution rendered as **zero principles** — an audit +surface the audit tool could not see. + +`.meta/design-principles.md` is the canonical, **operator-LOCKED** surface. This file is a stub and +carries no principle bodies, so there is no second copy to drift. + +| Now | Was | Principle | +|---|---|---| +| PR-001 | PR-BUILD-001 | Spec is the source of truth | +| PR-002 | PR-BUILD-002 | The script does deterministic checks only | +| PR-003 | PR-BUILD-003 | Pinned docs are crawled fresh | +| PR-004 | PR-BUILD-004 | TDD is necessary, not sufficient | +| PR-005 | PR-BUILD-005 | The verifier is read-only | +| PR-006 | PR-BUILD-006 | OPTIMIZE returns here for agentspec-backed implementation work | diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/build-protocol.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/build-protocol.md new file mode 100644 index 00000000..14d8df6e --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/build-protocol.md @@ -0,0 +1,121 @@ +# mutagent-builder — BUILD Protocol + +`mutagent-builder` is the authoritative ADL **② BUILD** owner. It implements validated AgentSpec 0.3.0 +resource cards; it does not specify new agents and does not judge eval outcomes. BUILD has TWO internal +phases — **PLAN → BUILD** — both owned by the Builder team (N05): the AI engineer expands the existing +`*plan-layout` / `#plan-repo-hierarchy` capability into a complete, doc-grounded translation plan, the +AI architect checks it **read-only** (READY | BLOCKED) **before any target write**, and only then the +same engineer executes the READY plan tests-first. This adds NO new stage, command, schema, or run file +— the plan lives in the PLAN section of the existing build report. + +## Inputs + +A BUILD run requires: + +1. a structurally + semantically valid `agentspec.yaml` (AgentSpec 0.3.0) — run the full validator, not + a field spot-check; +2. the optional colocated `agentspec.decisions.md` when the card sets `spec.decisionsRef` (the pair is + one bundle); +3. target root(s); +4. an EXPLICIT target selection — a `spec.targets[].id` (or set) — REQUIRED when the card declares more + than one target; a single target may default; +5. per selected target: `type` (harness|framework|platform|custom) · `name` · `artifact.format`/`path` · + `documentation[]` (crawled FRESH at build time) · optional `implementation.language`/`toolchain` + (code artifacts only); +6. optional approved remedy or EDD change request. + +Run `scripts/cli/run.sh scripts/handoff/validate-build-input.ts --spec --target ` +before dispatch when the parent session needs a deterministic input preflight. + +## 0.3.0 Build flow (B0–B9) + +| # | Phase | What happens | +|---|---|---| +| B0 | **Receive** | approved resource card with one `kind` and one-or-many `targets[]`. | +| B1 | **Select target(s)** | resolve the explicit target id/set; a single target may default. | +| B2 | **Preflight** | call the structural+semantic validator; confirm the kind body, resolved inbound `context[].access`, bounded `actions[]`, `artifact.format`/`path`, code `implementation`, `documentation[]`, capability fit, and the decision bundle. Route by **kind × selected target's type/name/artifact.format** (+ `implementation.language/toolchain` for generated code). | +| B3 | **PLAN** | engineer reads spec + target docs (fresh) + repo, and maps **each build-relevant requirement → target primitive/file/test/evidence**. Writes the frozen PLAN section of the build report (goal-based task grammar below). **No target writes.** | +| B4 | **Plan check** | architect checks the PLAN read-only against spec + docs + repo state: **READY** or **BLOCKED** (reason / operator question). **Still no target writes.** | +| B5 | **Engineer** | execute the READY plan — **tests first**, then implement. The engineer executes the checked plan, not an improvised structure. | +| B6 | **Gates** | lint · typecheck · build · test · coverage (`spec-impl-coverage.ts`) · target smoke. | +| B7 | **Verify** | architect independently re-checks actual output against spec + approved plan + cited docs (fidelity table). | +| B8 | **Disposition** | exactly one verdict: `PROCEED` · `STEER` (bounded amendment, cited) · `ABORT` (escalate, cited). | +| B9 | **Report** | plan-to-actual delta · fidelity/loss · EVALUATE handoff. | + +> **Brownfield / drift first.** Before B3, `ai-architect` may run `*sync-spec` when the implementation is +> brownfield or target code is newer than the spec: +> `scripts/cli/run.sh scripts/sync-spec/check-sync-spec.ts --spec --target [--json]`. +> On `missing-spec`/`needs-sync` it performs read-only analysis and emits a cited sync plan; `ai-engineer` +> applies the spec update under the gate, `*validate-spec` re-gates, and only then BUILD continues. + +## Goal-based PLAN contract — what "complete" means + +**A file list is not a plan.** Every implementation task in the frozen PLAN needs: a user-observable +**goal**, a bounded **task**, the **exact artifacts** (path/binding), the selected target +**components/primitives with rationale + doc source**, dependencies, and one or more **checks with +expected results**. A task cannot be READY when success depends only on "looks correct" or on an uncited +framework assumption. Behavioral checks that belong to EVALUATE are marked as such (not run at BUILD). + +The architect **refuses READY** when a task lacks a verifiable outcome, an exact artifact, a justified +component choice, or a check/expected-result. A BLOCKED plan states the missing evidence or the operator +question. No separate plan parser, schema, or command is introduced — this is the PLAN section of +`assets/templates/build-report.md.tpl`, frozen before writes and checked read-only. + +## Multi-target + custom-target resolver + +Resolve **each selected target independently**. Load its `documentation[]` by purpose and extract, into +an in-memory checklist: file shape, conventions, available context/action bindings, commands, +registration/deployment, and verification. A **custom** target is a normal target with path + doc +references — its conventions come from its linked authoritative docs, NOT a schema extension (F02). A +missing capability fit, path, artifact format, dead/contradictory guidance, or unsupported action +boundary **blocks only that target** and is reported as a gap — it does not fail the others. + +## Per-kind implementation paths (trace intent → target → tests → evidence) + +- **Agent** — persona/prompt fidelity, triggers, context/action bindings, skills/delegation, canonical + Workflow use, observability, tests. Map every intent SOP + derived job to Agent design → target output + → tests → evidence (SOP/jobs are shared intent, not Agent-only fields). Proof: the same intent builds + into at least a **markdown harness** target AND a **code-framework** target without changing normative intent. +- **Skill** — build a real skill package/instruction surface from Skill intent (do NOT route through the + unreleased Skill Builder). Trace purpose · activation/when-to-use · inputs/outputs · instruction + workflow · references · scripts/assets · host tools · failure behavior · verification. Proof: fresh + Claude and Codex installs discover and execute the built Skill as specified. +- **MultiAgent** — build the envelope, each embedded full member spec, the root orchestrator, and the + declared dispatch/watch wiring WITHOUT flattening members into labels. Trace member identity/version, + optional member intent ref, skills/subagents/observes resolution, composition order, deployment shape, + whole-system verification. Proof: dangling members are rejected; dispatch and observation stay distinct. +- **Workflow** — build/emit the target's native graph from the shared state/nodes/edges vocabulary. Trace + entry + terminal nodes, edge targets/conditions, state contract, reachability, and **explicit + bounded-loop evidence**. Proof: a returning edge passes ONLY with an enforceable `exitWhen`/`maxIterations`; + unbounded loops, missing edge targets, and unreported target limitations FAIL. + +## Coverage + fidelity gates + +Keep `@implements` module/test coverage for code tools where applicable (`spec-impl-coverage.ts`). Add +profile-aware checks for all implementation-bearing requirements, context/action operation boundaries, +retained LLM-facing descriptions, and explicit **unsupported/weakened dispositions**. New conformance +fixtures live under the builder scripts tree. + +## Architect checkpoints — PLAN check + VERIFY (read-only boundary) + +The architect stays **read-only** (source writes forbidden; only verdict artifacts allowed). Before BUILD +it checks the engineer's PLAN against spec + target docs + repo state (READY | BLOCKED). After BUILD it +independently checks actual output against spec + approved plan + cited docs, producing a +field/requirement **fidelity table**, verifying operator-approved exceptions, **rejecting unreported +loss**, and reporting every plan-to-actual deviation with an evidence-linked `PROCEED`/`STEER`/`ABORT`. + +## Build report + +Use `assets/templates/build-report.md.tpl`. The **PLAN** section is completed and architect-checked +READY **before** any target write; the **BUILD RESULT** section records actual evidence and deviations +after execution. Include: spec identity/version + `metadata.id`; selected target id/type/name + +artifact.format/path (+ code implementation details); pinned docs crawled; goal-based PLAN task table + +READY/BLOCKED; files written; TDD commands + results; `spec-impl-coverage` table; the fidelity/loss +table (silence about loss is a failure); verifier verdict; EVALUATE handoff paths. + +## Handoff to EVALUATE + +The handoff bundle contains `agentspec.yaml` (+ `agentspec.decisions.md` when referenced), the build +report, the implementation root, the trace/output sink location, and any `ChangeRequestResponse` when +BUILD was triggered by EDD. When code changed ahead of truth, the report also carries reverse-sync status +and the pending operator decision (Wave-3 lifecycle sync). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/optimize-handoff.md b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/optimize-handoff.md new file mode 100644 index 00000000..a19d4ba6 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/references/workflows/optimize-handoff.md @@ -0,0 +1,23 @@ +# mutagent-builder — OPTIMIZE Handoff + +Evaluator remains judge-only. Diagnostics remains RCA/apply-dispatch for non-agentspec targets. When a +remedy is agentspec-backed and requires code/spec/implementation change, the implementation leg returns +to BUILD. + +## EDD request path + +1. Evaluator emits `AddChangeRequest` / `EddChangeRequest` with grounded failing cases, remedy target + (`agentspec` or `impl`), and proposed remedy hypothesis. +2. `ai-engineer` validates and reproduces the grounded defect. +3. If `remedyTarget: agentspec`, `ai-engineer` amends the Definition, validates it, reruns BUILD, TDD, + and coverage. Set `rebuilt: true` in `ChangeRequestResponse`. +4. If `remedyTarget: impl`, `ai-engineer` amends implementation only, then reruns TDD and coverage. +5. `ai-architect` verifies and returns `PROCEED | STEER | ABORT`. +6. Evaluator reruns after `ChangeRequestResponse`; BUILD does not self-certify eval success. + +## Diagnostics apply branch + +If diagnostics has an approved remedy packet for an agentspec-backed subject and the remedy requires a +code/spec/implementation change, diagnostics emits the packet to `mutagent-builder`; `ai-engineer` +implements/amends; `ai-architect` verifies; evaluator reruns. Diagnostics apply workers continue to own +legacy local markdown targets, remote REST targets, report-only, and non-agentspec adapter cases. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/cli/run.sh b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/cli/run.sh new file mode 100644 index 00000000..c6e7359d --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/cli/run.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# scripts/cli/run.sh — bun→pnpm→npm fallback selector + .sh dispatch. +# Usage: scripts/cli/run.sh [args...] +# scripts/cli/run.sh --selftest +# +# This wrapper provides consistent script invocation across operator environments. +# All agent Bash() calls to TypeScript OR shell scripts MUST go through this wrapper: +# Bash("scripts/cli/run.sh scripts/validate/validate-spec.ts ...") +# +# Platform matrix — which tier fires when: +# Tier 1 (bun) : bun is on PATH (local dev, most operator installs) +# Tier 2 (pnpm-tsx) : bun absent, pnpm on PATH (corporate Node setups, pnpm-only CIs) +# Tier 3 (npx-tsx) : bun + pnpm absent, npx on PATH (vanilla Node, GitHub Actions default) +# Tier 4 (error) : none of the above — exits 1 with install guidance +# .sh scripts bypass all tiers and run directly via bash regardless of PATH state. + +set -e + +SCRIPT="$1" + +# --selftest: print selected runtime and exit 0 (portability probe) +if [ "$SCRIPT" = "--selftest" ]; then + if command -v bun >/dev/null 2>&1; then + echo "run.sh selftest: tier=1 runtime=bun version=$(bun --version 2>/dev/null || echo unknown)" + elif command -v pnpm >/dev/null 2>&1; then + echo "run.sh selftest: tier=2 runtime=pnpm-tsx version=$(pnpm --version 2>/dev/null || echo unknown)" + elif command -v npx >/dev/null 2>&1; then + echo "run.sh selftest: tier=3 runtime=npx-tsx version=$(node --version 2>/dev/null || echo unknown)" + else + echo "run.sh selftest: tier=4 runtime=none (install bun: curl -fsSL https://bun.sh/install | bash)" + exit 1 + fi + exit 0 +fi + +shift + +if [ -z "$SCRIPT" ]; then + echo "ERROR: no script path provided" >&2 + echo "Usage: run.sh [args...]" >&2 + echo " run.sh --selftest" >&2 + exit 1 +fi + +# .sh files: execute directly via bash (no TS runtime needed) +case "$SCRIPT" in + *.sh) exec bash "$SCRIPT" "$@" ;; +esac + +# A runtime that resolves under /mnt/* is a WINDOWS exe reached through WSL +# interop — it cannot accept the POSIX paths this selector passes (observed: +# WSL node + Windows-side pnpm → /home/... re-anchored to C:\home\... → +# ERR_MODULE_NOT_FOUND). Skip it so a native tier runs instead. +native_cmd() { + _p="$(command -v "$1" 2>/dev/null)" || return 1 + case "$_p" in /mnt/*) return 1 ;; esac + return 0 +} + +if native_cmd bun; then + exec bun run "$SCRIPT" "$@" +elif native_cmd pnpm; then + echo "[run.sh] runtime tier 2: pnpm dlx tsx (bun not on PATH). TypeScript entrypoints use the portable isEntrypoint() guard." >&2 + exec pnpm dlx tsx "$SCRIPT" "$@" +elif native_cmd npx; then + echo "[run.sh] runtime tier 3: npx tsx (bun and pnpm not on PATH). TypeScript entrypoints use the portable isEntrypoint() guard." >&2 + exec npx -y tsx "$SCRIPT" "$@" +else + echo "ERROR: mutagent-builder requires bun, pnpm, or npm/npx to run TypeScript scripts" >&2 + echo "Install bun: curl -fsSL https://bun.sh/install | bash" >&2 + exit 1 +fi diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/handoff/validate-build-input.ts b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/handoff/validate-build-input.ts new file mode 100644 index 00000000..7589ff54 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/handoff/validate-build-input.ts @@ -0,0 +1,76 @@ +#!/usr/bin/env bun +/** Lightweight input preflight for `mutagent-builder` BUILD dispatch. */ +import * as fs from "node:fs"; +import * as path from "node:path"; +import { parse as parseYaml } from "yaml"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +interface Args { spec?: string; target?: string; json: boolean } +interface Result { ok: boolean; specPath: string | null; targetRoot: string | null; reason: string; specId: string | null; kind: string | null; targetCount: number } +const KINDS = ["Agent", "Skill", "MultiAgent", "Workflow"]; + +function parseArgs(argv: string[]): Args { + const args: Args = { json: false }; + for (let i = 0; i < argv.length; i++) { + const arg = argv[i]; + if (arg === "--spec") args.spec = argv[++i]; + else if (arg === "--target") args.target = argv[++i]; + else if (arg === "--json") args.json = true; + else if (arg === "--help" || arg === "-h") { + console.log("Usage: scripts/cli/run.sh scripts/handoff/validate-build-input.ts --spec --target [--json]"); + process.exit(0); + } else throw new Error(`unknown argument: ${arg}`); + } + return args; +} + +function check(args: Args): Result { + if (!args.spec) return { ok: false, specPath: null, targetRoot: args.target ?? null, reason: "spec: --spec is required", specId: null, kind: null, targetCount: 0 }; + if (!args.target) return { ok: false, specPath: args.spec, targetRoot: null, reason: "target: --target is required", specId: null, kind: null, targetCount: 0 }; + const specPath = path.resolve(args.spec); + const targetRoot = path.resolve(args.target); + try { + if (!fs.statSync(specPath).isFile()) throw new Error("not a file"); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { ok: false, specPath, targetRoot, reason: `spec: unreadable spec: ${message}`, specId: null, kind: null, targetCount: 0 }; + } + try { + if (!fs.statSync(targetRoot).isDirectory()) throw new Error("not a directory"); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { ok: false, specPath, targetRoot, reason: `target: unreadable target root: ${message}`, specId: null, kind: null, targetCount: 0 }; + } + let parsed: any; + try { + parsed = parseYaml(fs.readFileSync(specPath, "utf8")); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { ok: false, specPath, targetRoot, reason: `spec: YAML parse failed: ${message}`, specId: null, kind: null, targetCount: 0 }; + } + // AgentSpec 0.3.0 envelope: metadata.id + kind (strict discriminator) + spec.targets[]. + const specId = parsed?.metadata?.id ?? null; + const kind = parsed?.kind ?? null; + const targets = Array.isArray(parsed?.spec?.targets) ? parsed.spec.targets : []; + const targetCount = targets.length; + if (!specId) return { ok: false, specPath, targetRoot, reason: "metadata.id: missing", specId, kind, targetCount }; + if (!kind || !KINDS.includes(kind)) return { ok: false, specPath, targetRoot, reason: `kind: must be one of ${KINDS.join(" | ")}`, specId, kind, targetCount }; + if (targetCount < 1) return { ok: false, specPath, targetRoot, reason: "spec.targets: at least one target is required to build", specId, kind, targetCount }; + return { ok: true, specPath, targetRoot, reason: "build inputs ready", specId, kind, targetCount }; +} + +export function runCli(argv: string[]): number { + let args: Args; + try { args = parseArgs(argv); } + catch (error) { + const result: Result = { ok: false, specPath: null, targetRoot: null, reason: `args: ${error instanceof Error ? error.message : String(error)}`, specId: null, kind: null, targetCount: 0 }; + console.error(JSON.stringify(result, null, 2)); + return 1; + } + const result = check(args); + const output = args.json ? JSON.stringify(result, null, 2) : `[validate-build-input] ${result.ok ? "PASS" : "FAIL"}: ${result.reason}`; + if (result.ok) console.log(output); else console.error(output); + return result.ok ? 0 : 1; +} + +if (isEntrypoint(import.meta.url)) process.exit(runCli(process.argv.slice(2))); diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/lib/entrypoint.ts b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/lib/entrypoint.ts new file mode 100644 index 00000000..9d509717 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/lib/entrypoint.ts @@ -0,0 +1,41 @@ +/** + * scripts/lib/entrypoint.ts — the portable "am I the entrypoint?" check. + * + * WHY THIS EXISTS: `import.meta.main` is NOT portable. Bun always defines it; Node only + * added it natively in v22.18 / v24.2. Under `scripts/cli/run.sh` tiers 2 and 3 + * (`pnpm exec tsx`, `npx tsx`) on Node < 22.18 — which includes the Node 20 this repo's + * CI pins — `import.meta.main` is `undefined`, so `if (import.meta.main)` is false, the + * CLI body never runs, and the process EXITS 0 HAVING DONE NOTHING. That is how + * `*validate-spec` reported PASS without parsing anything. A gate that reports success + * without checking is worse than one that errors, so every entrypoint guard in this + * package routes through here. + * + * HOW: compare this module's own path to the path the runtime was invoked with + * (`process.argv[1]`). Both sides are realpath'd, so a symlinked skill install — the + * deliberate rapid-iteration dev setup — still matches. Semantics are identical to Bun's + * `import.meta.main`: true only when the module is executed DIRECTLY, false when it is + * imported. Verified on bun, Node 20 + tsx, and Node 22 + tsx. + * + * Usage: if (isEntrypoint(import.meta.url)) { … } + */ +import { realpathSync } from "node:fs"; +import { fileURLToPath } from "node:url"; + +export function isEntrypoint(moduleUrl: string): boolean { + const invoked = process.argv[1]; + if (!invoked) return false; + let self: string; + try { + self = fileURLToPath(moduleUrl); + } catch { + return false; + } + const resolve = (p: string): string => { + try { + return realpathSync(p); + } catch { + return p; + } + }; + return resolve(self) === resolve(invoked); +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts new file mode 100644 index 00000000..b79b1f4b --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/sync-spec/check-sync-spec.ts @@ -0,0 +1,524 @@ +#!/usr/bin/env bun +/** + * scripts/sync-spec/check-sync-spec.ts + * + * Deterministic freshness probe for the `ai-architect #sync-spec` mode. AgentSpec's `*sync-spec` + * command delegates here (Helix-mediated); `*build` reuses it build-internally on drift. + * + * ACCEPTED LIMITATION — recency ≠ divergence. This probe measures RECENCY (git commit timestamps of + * impl/eval paths vs the card's status.updated_at), not semantic DIVERGENCE: a commit that only + * touched whitespace still reads as "newer", so a `needs-sync` verdict means "the impl moved after the + * card was stamped", not "the impl and the spec actually disagree". The reconcile step (`ai-architect + * #sync-spec`) is what confirms real divergence; a timestamp probe cannot, and deliberately does not, try. + * + * CLI: + * scripts/cli/run.sh scripts/sync-spec/check-sync-spec.ts --spec --target [--json] + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { spawnSync } from "node:child_process"; +import { parse as parseYaml } from "yaml"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +export interface Freshness { + updatedAt?: string | null; + gitCommitEpoch: number | null; + fileMtimeEpoch: number | null; + effectiveEpoch: number | null; +} + +/** + * The eval-leg (third leg of the def → impl → eval triad, W2I5) freshness verdict. + * `not-applicable` = no eval-criteria artifact was requested or located (the 2-leg + * spec↔impl reconcile is unaffected — additive). The other three MIRROR the spec-leg + * semantics so both legs agree on "impl is newer → reconcile". + */ +export type EvalLegStatus = "not-applicable" | "missing-eval" | "in-sync" | "needs-sync" | "unknown"; + +export interface SyncSpecStatus { + status: "missing-spec" | "in-sync" | "needs-sync" | "unknown" | "error"; + specPath: string | null; + targetRoot: string; + specFreshness: { updatedAt: string | null; gitCommitEpoch: number | null; fileMtimeEpoch: number | null; effectiveEpoch: number | null }; + codeFreshness: { gitCommitEpoch: number | null; fileMtimeEpoch: number | null; effectiveEpoch: number | null; newestPath: string | null }; + /** + * The EVAL leg (W2I5 · KP-003). Detects when the impl amended past the eval criteria + * that ground the subject's evaluation. Subject-kind-agnostic at THIS layer — the + * predicate only stats the criteria artifact's freshness vs the impl; WHICH criteria + * (agent/skill eval-suite vs code code-quality) is the reconcile's concern + * (`ai-architect #sync-spec` + evaluator `sync-eval-criteria.ts`). + */ + evalStatus: EvalLegStatus; + evalFreshness: { path: string | null; updatedAt: string | null; gitCommitEpoch: number | null; fileMtimeEpoch: number | null; effectiveEpoch: number | null }; + reason: string; +} + +interface CliArgs { + spec?: string; + target?: string; + evalCriteria?: string; + json: boolean; +} + +function emptySpecFreshness(): SyncSpecStatus["specFreshness"] { + return { updatedAt: null, gitCommitEpoch: null, fileMtimeEpoch: null, effectiveEpoch: null }; +} + +function emptyCodeFreshness(targetRoot = ""): SyncSpecStatus["codeFreshness"] { + void targetRoot; + return { gitCommitEpoch: null, fileMtimeEpoch: null, effectiveEpoch: null, newestPath: null }; +} + +function emptyEvalFreshness(): SyncSpecStatus["evalFreshness"] { + return { path: null, updatedAt: null, gitCommitEpoch: null, fileMtimeEpoch: null, effectiveEpoch: null }; +} + +/** The eval leg is not-applicable when no criteria artifact was requested/located. */ +function notApplicableEval(): { evalStatus: EvalLegStatus; evalFreshness: SyncSpecStatus["evalFreshness"] } { + return { evalStatus: "not-applicable", evalFreshness: emptyEvalFreshness() }; +} + +function epochSeconds(ms: number): number | null { + return Number.isFinite(ms) ? Math.floor(ms / 1000) : null; +} + +function normalizeCandidate(base: string, candidate: string): string { + return path.isAbsolute(candidate) ? candidate : path.resolve(base, candidate); +} + +function isPrunedDir(absDir: string, targetRoot: string): boolean { + const rel = path.relative(targetRoot, absDir); + if (!rel || rel === "") return false; + const parts = rel.split(path.sep); + if (parts.includes("node_modules") || parts.includes(".git") || parts.includes("dist") || parts.includes("coverage")) return true; + const mutagentIdx = parts.indexOf(".mutagent"); + if (mutagentIdx >= 0 && parts[mutagentIdx + 2] === "runs") return true; // .mutagent//runs + // The evaluator's namespaced artifact root (.mutagent/evaluator/**) is eval OUTPUT, never + // implementation — pruning it keeps eval-suite criteria / datasets from masquerading as impl + // drift (they are the EVAL leg, compared separately). W2I5. + if (mutagentIdx >= 0 && parts[mutagentIdx + 1] === "evaluator") return true; + return false; +} + +function isGeneratedReport(absFile: string, targetRoot: string): boolean { + const rel = path.relative(targetRoot, absFile); + const parts = rel.split(path.sep); + const file = parts.at(-1) ?? ""; + if (!parts.includes(".mutagent")) return false; + if (/^(build-)?report\.(md|json|html)$/i.test(file)) return true; + if (/^verdict\.(md|json)$/i.test(file)) return true; + return false; +} + +function walkFiles(root: string, predicate: (abs: string) => boolean): string[] { + const out: string[] = []; + const stack = [root]; + while (stack.length) { + const current = stack.pop()!; + let entries: fs.Dirent[]; + try { + entries = fs.readdirSync(current, { withFileTypes: true }); + } catch { + continue; + } + for (const entry of entries) { + const abs = path.join(current, entry.name); + if (entry.isDirectory()) { + if (!isPrunedDir(abs, root)) stack.push(abs); + } else if (entry.isFile() && predicate(abs)) { + out.push(abs); + } + } + } + return out.sort(); +} + +function locateSpec(targetRoot: string, explicitSpec?: string): string | null { + if (explicitSpec) { + const abs = normalizeCandidate(process.cwd(), explicitSpec); + try { + const stat = fs.statSync(abs); + return stat.isFile() ? abs : null; + } catch { + return null; + } + } + + const direct = path.join(targetRoot, "agentspec.yaml"); + if (fs.existsSync(direct) && fs.statSync(direct).isFile()) return direct; + + const mutagentSpecs = path.join(targetRoot, ".mutagent", "specs"); + if (fs.existsSync(mutagentSpecs)) { + const found = walkFiles(mutagentSpecs, (abs) => path.basename(abs) === "agentspec.yaml"); + if (found.length) return found[0]; + } + + const found = walkFiles(targetRoot, (abs) => path.basename(abs) === "agentspec.yaml"); + return found[0] ?? null; +} + +/** + * The card-side freshness anchor is the INTERNAL top-level `status.updated_at` stamp (agentspec + * ORCH-07 / R7 — supersedes the 0.2 `meta.loop_state.updated_at` location). It is the authoritative + * "when the card was last reconciled/stamped"; the impl side is compared against it. A malformed + * YAML is an error; a missing/malformed stamp yields a null epoch (→ an honest `unknown` verdict, we + * never fall back to mtime). + */ +function parseUpdatedAt(specPath: string): { updatedAt: string | null; epoch: number | null; error?: string } { + let parsed: unknown; + try { + parsed = parseYaml(fs.readFileSync(specPath, "utf8")); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { updatedAt: null, epoch: null, error: `specPath: failed to parse YAML: ${message}` }; + } + const updatedAt = (parsed as any)?.status?.updated_at; + if (typeof updatedAt !== "string") return { updatedAt: null, epoch: null }; + const ms = Date.parse(updatedAt); + if (!Number.isFinite(ms)) return { updatedAt: null, epoch: null }; + return { updatedAt, epoch: Math.floor(ms / 1000) }; +} + +function gitEpochForPaths(targetRoot: string, files: string[]): number | null { + if (!files.length) return null; + let best: number | null = null; + for (let i = 0; i < files.length; i += 100) { + const batch = files.slice(i, i + 100).map((f) => path.relative(targetRoot, f)); + const result = spawnSync("git", ["-C", targetRoot, "log", "-1", "--format=%ct", "--", ...batch], { + encoding: "utf8", + stdio: ["ignore", "pipe", "ignore"], + }); + if (result.status !== 0) continue; + const text = result.stdout.trim().split(/\s+/).find(Boolean); + const n = text ? Number(text) : NaN; + if (Number.isFinite(n)) best = best == null ? n : Math.max(best, n); + } + return best; +} + +function fileMtimeEpoch(file: string): number | null { + try { + return epochSeconds(fs.statSync(file).mtimeMs); + } catch { + return null; + } +} + +function newestMtime(files: string[]): { epoch: number | null; path: string | null } { + let bestEpoch: number | null = null; + let bestPath: string | null = null; + for (const file of files) { + const epoch = fileMtimeEpoch(file); + if (epoch != null && (bestEpoch == null || epoch > bestEpoch)) { + bestEpoch = epoch; + bestPath = file; + } + } + return { epoch: bestEpoch, path: bestPath }; +} + +function implementationFiles(targetRoot: string, specPath: string | null, evalPath?: string | null): string[] { + const normalizedSpec = specPath ? path.resolve(specPath) : null; + const normalizedEval = evalPath ? path.resolve(evalPath) : null; + return walkFiles(targetRoot, (abs) => { + const resolved = path.resolve(abs); + if (normalizedSpec && resolved === normalizedSpec) return false; + // The eval-criteria artifact is the EVAL leg, never impl — exclude it so it can never + // count as its own drift source (mirror of the spec exclusion). W2I5. + if (normalizedEval && resolved === normalizedEval) return false; + if (isGeneratedReport(abs, targetRoot)) return false; + return true; + }); +} + +/** + * Locate the eval-criteria artifact (the EVAL leg's freshness anchor). An explicit path + * wins; otherwise auto-locate under the evaluator's namespaced root + * (`.mutagent/evaluator/living-suite/*.{yaml,yml,json}` — the discovered eval-suite + * criteria) or a conventional criteria file at the target root. Returns `{ path, existed }`: + * an explicit-but-missing path yields `existed:false` (→ `missing-eval`); no path found + * yields `path:null` (→ `not-applicable`, additive no-op). W2I5. + */ +function locateEvalCriteria(targetRoot: string, explicit?: string): { path: string | null; existed: boolean } { + if (explicit) { + const abs = normalizeCandidate(process.cwd(), explicit); + try { + return { path: abs, existed: fs.statSync(abs).isFile() }; + } catch { + return { path: abs, existed: false }; + } + } + const criteriaExt = (abs: string): boolean => /\.(ya?ml|json)$/i.test(abs); + const livingSuite = path.join(targetRoot, ".mutagent", "evaluator", "living-suite"); + if (fs.existsSync(livingSuite)) { + const found = walkFiles(livingSuite, criteriaExt); + if (found.length) return { path: found[0], existed: true }; + } + for (const name of ["eval-criteria", "code-quality-criteria"]) { + for (const ext of ["yaml", "yml", "json"]) { + const candidate = path.join(targetRoot, `${name}.${ext}`); + if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return { path: candidate, existed: true }; + } + } + return { path: null, existed: false }; +} + +/** Parse an optional freshness marker from an eval-criteria artifact (best-effort). */ +function parseEvalUpdatedAt(evalPath: string): { updatedAt: string | null; epoch: number | null } { + let parsed: unknown; + try { + parsed = parseYaml(fs.readFileSync(evalPath, "utf8")); + } catch { + return { updatedAt: null, epoch: null }; + } + const raw = + (parsed as any)?.meta?.loop_state?.updated_at ?? + (parsed as any)?.updatedAt ?? + (parsed as any)?.updated_at ?? + (parsed as any)?.generatedAt; + if (typeof raw !== "string") return { updatedAt: null, epoch: null }; + const ms = Date.parse(raw); + if (!Number.isFinite(ms)) return { updatedAt: null, epoch: null }; + return { updatedAt: raw, epoch: Math.floor(ms / 1000) }; +} + +/** + * Compute the EVAL leg (status + freshness) given the code (impl) effective epoch. The + * `not-applicable` / `missing-eval` / `in-sync` / `needs-sync` verdict mirrors the spec + * leg's semantics so the two legs agree on "impl newer → reconcile". Deterministic. W2I5. + */ +function evalLeg( + targetRoot: string, + explicit: string | undefined, + codeGitEpoch: number | null, +): { evalStatus: EvalLegStatus; evalFreshness: SyncSpecStatus["evalFreshness"] } { + const located = locateEvalCriteria(targetRoot, explicit); + if (located.path == null) return notApplicableEval(); + if (!located.existed) { + return { evalStatus: "missing-eval", evalFreshness: { ...emptyEvalFreshness(), path: located.path } }; + } + const updated = parseEvalUpdatedAt(located.path); + const git = gitEpochForPaths(targetRoot, [located.path]); + const mtime = fileMtimeEpoch(located.path); // reported only — never drives the verdict + const evalFreshness = { + path: located.path, + updatedAt: updated.updatedAt, + gitCommitEpoch: git, + fileMtimeEpoch: mtime, + effectiveEpoch: git, // GIT-anchored: the criteria's last commit (no mtime) + }; + // GIT-derived + honest UNKNOWN: eval drifts if the impl was committed after the criteria's last + // commit. When either side lacks git history we refuse an mtime guess and report `unknown`. + let evalStatus: EvalLegStatus; + if (codeGitEpoch == null || git == null) evalStatus = "unknown"; + else evalStatus = codeGitEpoch > git ? "needs-sync" : "in-sync"; + return { evalStatus, evalFreshness }; +} + +/** + * The legs that DRIFTED — the triad's headline surface. `spec` drifts on `missing-spec` + * (cold construct) or `needs-sync`; `eval` drifts on `missing-eval` or `needs-sync`. The + * reconcile (ai-architect) reads this to reconcile BOTH legs when an impl amends. W2I5. + */ +export function driftedLegs(status: SyncSpecStatus): Array<"spec" | "eval"> { + const legs: Array<"spec" | "eval"> = []; + if (status.status === "missing-spec" || status.status === "needs-sync") legs.push("spec"); + if (status.evalStatus === "missing-eval" || status.evalStatus === "needs-sync") legs.push("eval"); + return legs; +} + +export function checkSyncSpec(args: { targetRoot: string; specPath?: string; evalCriteriaPath?: string }): SyncSpecStatus { + const targetRoot = path.resolve(args.targetRoot); + let targetStat: fs.Stats; + try { + targetStat = fs.statSync(targetRoot); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + return { + status: "error", + specPath: null, + targetRoot, + specFreshness: emptySpecFreshness(), + codeFreshness: emptyCodeFreshness(), + ...notApplicableEval(), + reason: `targetRoot: unreadable target root: ${message}`, + }; + } + if (!targetStat.isDirectory()) { + return { + status: "error", + specPath: null, + targetRoot, + specFreshness: emptySpecFreshness(), + codeFreshness: emptyCodeFreshness(), + ...notApplicableEval(), + reason: "targetRoot: target root is not a directory", + }; + } + + const specPath = locateSpec(targetRoot, args.specPath); + if (!specPath) { + const files = implementationFiles(targetRoot, null, locateEvalCriteria(targetRoot, args.evalCriteriaPath).path); + const newest = newestMtime(files); + const codeGit = gitEpochForPaths(targetRoot, files); // GIT-derived (no mtime in the verdict) + return { + status: "missing-spec", + specPath: null, + targetRoot, + specFreshness: emptySpecFreshness(), + codeFreshness: { + gitCommitEpoch: codeGit, + fileMtimeEpoch: newest.epoch, // reported only + effectiveEpoch: codeGit, + newestPath: newest.path, + }, + ...evalLeg(targetRoot, args.evalCriteriaPath, codeGit), + reason: "no agentspec.yaml found; derive spec from implementation", + }; + } + + const updated = parseUpdatedAt(specPath); + if (updated.error) { + return { + status: "error", + specPath, + targetRoot, + specFreshness: emptySpecFreshness(), + codeFreshness: emptyCodeFreshness(), + ...notApplicableEval(), + reason: updated.error, + }; + } + + const specGit = gitEpochForPaths(targetRoot, [specPath]); + const specMtime = fileMtimeEpoch(specPath); + const cardEpoch = updated.epoch; // card-side freshness = status.updated_at ONLY (authoritative) + const specFreshness = { + updatedAt: updated.updatedAt, + gitCommitEpoch: specGit, + fileMtimeEpoch: specMtime, // reported only — never drives the verdict + effectiveEpoch: cardEpoch, + }; + + const evalLocated = locateEvalCriteria(targetRoot, args.evalCriteriaPath); + const files = implementationFiles(targetRoot, specPath, evalLocated.path); + const codeGit = gitEpochForPaths(targetRoot, files); // GIT-derived impl drift (no mtime) + const codeMtime = newestMtime(files); + const codeFreshness = { + gitCommitEpoch: codeGit, + fileMtimeEpoch: codeMtime.epoch, // reported only + effectiveEpoch: codeGit, + newestPath: codeMtime.path, + }; + const evalResult = evalLeg(targetRoot, args.evalCriteriaPath, codeGit); + + // Honest UNKNOWN over an mtime guess: impl drift is GIT-derived, so if the impl paths carry no git + // history (not a repo, or untracked/uncommitted files) we cannot compare — and if the card carries + // no status.updated_at stamp we have no card-side anchor. Either way → `unknown`, never mtime. + if (codeGit == null) { + return { + status: "unknown", + specPath, + targetRoot, + specFreshness, + codeFreshness, + ...evalResult, + reason: + "implementation drift cannot be determined from git (not a repo, or impl files are untracked); refusing an mtime-based verdict", + }; + } + if (cardEpoch == null) { + return { + status: "unknown", + specPath, + targetRoot, + specFreshness, + codeFreshness, + ...evalResult, + reason: "card carries no status.updated_at stamp to anchor freshness against", + }; + } + + if (codeGit > cardEpoch) { + return { + status: "needs-sync", + specPath, + targetRoot, + specFreshness, + codeFreshness, + ...evalResult, + reason: "implementation changed in git after the card's status.updated_at", + }; + } + + return { + status: "in-sync", + specPath, + targetRoot, + specFreshness, + codeFreshness, + ...evalResult, + reason: "no implementation commits newer than the card's status.updated_at", + }; +} + +function parseArgs(argv: string[]): CliArgs { + const args: CliArgs = { json: false }; + for (let i = 0; i < argv.length; i++) { + const arg = argv[i]; + if (arg === "--json") args.json = true; + else if (arg === "--spec") args.spec = argv[++i]; + else if (arg === "--target") args.target = argv[++i]; + else if (arg === "--eval-criteria") args.evalCriteria = argv[++i]; + else if (arg === "--help" || arg === "-h") { + console.log("Usage: scripts/cli/run.sh scripts/sync-spec/check-sync-spec.ts --spec --target [--eval-criteria ] [--json]"); + process.exit(0); + } else { + throw new Error(`unknown argument: ${arg}`); + } + } + if (!args.target) throw new Error("--target is required"); + return args; +} + +function formatSummary(status: SyncSpecStatus): string { + const lines = [ + `[sync-spec] ${status.status}: ${status.reason}`, + `targetRoot: ${status.targetRoot}`, + `specPath: ${status.specPath ?? ""}`, + `specFreshness: updatedAt=${status.specFreshness.updatedAt ?? "null"} git=${status.specFreshness.gitCommitEpoch ?? "null"} mtime=${status.specFreshness.fileMtimeEpoch ?? "null"} effective=${status.specFreshness.effectiveEpoch ?? "null"}`, + `codeFreshness: git=${status.codeFreshness.gitCommitEpoch ?? "null"} mtime=${status.codeFreshness.fileMtimeEpoch ?? "null"} effective=${status.codeFreshness.effectiveEpoch ?? "null"} newestPath=${status.codeFreshness.newestPath ?? "null"}`, + `evalStatus: ${status.evalStatus} (eval leg — W2I5 triad)`, + `evalFreshness: path=${status.evalFreshness.path ?? ""} updatedAt=${status.evalFreshness.updatedAt ?? "null"} git=${status.evalFreshness.gitCommitEpoch ?? "null"} mtime=${status.evalFreshness.fileMtimeEpoch ?? "null"} effective=${status.evalFreshness.effectiveEpoch ?? "null"}`, + `driftedLegs: ${driftedLegs(status).join("+") || ""}`, + ]; + return lines.join("\n"); +} + +export function runCli(argv: string[]): number { + let args: CliArgs; + try { + args = parseArgs(argv); + } catch (error) { + const reason = error instanceof Error ? error.message : String(error); + const status: SyncSpecStatus = { + status: "error", + specPath: null, + targetRoot: "", + specFreshness: emptySpecFreshness(), + codeFreshness: emptyCodeFreshness(), + ...notApplicableEval(), + reason: `args: ${reason}`, + }; + console.error(JSON.stringify(status, null, 2)); + return 1; + } + const status = checkSyncSpec({ targetRoot: args.target!, specPath: args.spec, evalCriteriaPath: args.evalCriteria }); + const out = args.json ? JSON.stringify(status, null, 2) : formatSummary(status); + if (status.status === "error") console.error(out); + else console.log(out); + return status.status === "error" ? 1 : 0; +} + +if (isEntrypoint(import.meta.url)) process.exit(runCli(process.argv.slice(2))); diff --git a/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts new file mode 100644 index 00000000..23f417c4 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-builder/scripts/verify/spec-impl-coverage.ts @@ -0,0 +1,185 @@ +/** + * scripts/verify/spec-impl-coverage.ts + * The BUILD-FAITHFULNESS gate (PR-024) — assert every spec-declared code tool is implemented + tested. + * Type A — Pure core (computeCoverage, no I/O) + a thin guarded CLI. Mirrors validate-spec.ts. + * + * WHY: TDD proves the code that EXISTS passes; it is SILENT on whether all the code the SPEC requires + * exists (a dropped tool has no test, so nothing fails). A build is GREEN only when TDD passes AND + * this gate passes. The dogfood sim shipped a scaffold missing `collect-range` with 27 green tests — + * this gate makes that a STEER instead. + * + * CONVENTION: each implementing module carries `// @implements `; ≥1 test references that + * module (by basename or the same marker). The actor DECLARES the mapping in code; this script VERIFIES + * completeness against the spec; the Verifier RE-RUNS it (Context-Inversion — never trusts the actor). + * + * Usage: scripts/cli/run.sh scripts/verify/spec-impl-coverage.ts + * exit 0 = every code capability covered → "[coverage] PASS" + * exit 1 = at least one uncovered capability (a STEER) + * + * AgentSpec 0.3.0: reads `spec.capabilities.code[].id` (0.2's `definition.tools.code` retired, N01). + */ + +import * as fs from "node:fs"; +import * as path from "node:path"; +import { parse as parseYaml } from "yaml"; +import { isEntrypoint } from "../lib/entrypoint.ts"; + +/** One spec code-tool's coverage status. */ +export interface CoverageEntry { + id: string; + module: string | null; + test: string | null; + covered: boolean; + reason?: string; +} + +export interface CoverageResult { + ok: boolean; + entries: CoverageEntry[]; + /** job.backed_by refs (P2) that don't resolve to a declared code-tool id — a spec defect. */ + danglingBackedBy: string[]; +} + +/** A scanned file. Pure inputs so the core is unit-testable without disk. */ +export interface ScannedFile { + path: string; + content: string; +} + +/** `@implements ` marker matcher — id is treated literally (regex-escaped). */ +function implementsMarker(id: string): RegExp { + const esc = id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); + return new RegExp(`@implements\\s+${esc}(?:\\s|$)`, "m"); +} + +/** + * PURE core. For each declared code-tool id, require (a) a src file carrying `// @implements ` + * AND (b) ≥1 test file referencing that module (by basename) or carrying the same marker. Also flags + * job `backed_by` refs that don't resolve to a declared tool id. No I/O, never throws. + */ +export function computeCoverage( + toolIds: string[], + srcFiles: ScannedFile[], + testFiles: ScannedFile[], + backedByRefs: string[] = [], +): CoverageResult { + const entries: CoverageEntry[] = []; + for (const id of toolIds) { + const re = implementsMarker(id); + const mod = srcFiles.find((f) => re.test(f.content)) ?? null; + let test: ScannedFile | null = null; + if (mod) { + const base = path.basename(mod.path).replace(/\.ts$/, ""); + test = + testFiles.find((t) => t.content.includes(base) || re.test(t.content)) ?? null; + } + const covered = Boolean(mod) && Boolean(test); + entries.push({ + id, + module: mod ? mod.path : null, + test: test ? test.path : null, + covered, + reason: !mod + ? `no module carries \`// @implements ${id}\`` + : !test + ? `module ${path.basename(mod.path)} has no test referencing it` + : undefined, + }); + } + const declared = new Set(toolIds); + const danglingBackedBy = [...new Set(backedByRefs)].filter((r) => !declared.has(r)); + const ok = entries.every((e) => e.covered) && danglingBackedBy.length === 0; + return { ok, entries, danglingBackedBy }; +} + +/** Recursively collect .ts files under a dir (excluding node_modules / dotdirs). */ +function walkTs(dir: string): ScannedFile[] { + const out: ScannedFile[] = []; + const walk = (d: string): void => { + let ents: fs.Dirent[]; + try { + ents = fs.readdirSync(d, { withFileTypes: true }); + } catch { + return; + } + for (const e of ents) { + if (e.name === "node_modules" || e.name.startsWith(".")) continue; + const full = path.join(d, e.name); + if (e.isDirectory()) walk(full); + else if (e.isFile() && e.name.endsWith(".ts")) + out.push({ path: full, content: fs.readFileSync(full, "utf-8") }); + } + }; + walk(path.resolve(dir)); + return out; +} + +/** + * Read a spec + scaffold from disk and compute coverage. Throws only on an unreadable spec file. + * AgentSpec 0.3.0: the code capabilities live at `spec.capabilities.code[].id` (0.2's + * `definition.tools.code` is retired, N01). 0.3.0 jobs (`spec.intent.jobs[]`) do NOT carry a + * `backed_by` ref, so the dangling-backed_by check is vacuous here (the pure `computeCoverage` core + * still supports the check for callers that supply refs directly). + */ +export function coverageForScaffold( + specPath: string, + scaffoldDir: string, +): CoverageResult { + const spec = parseYaml(fs.readFileSync(path.resolve(specPath), "utf-8")) as Record< + string, + unknown + >; + const specBlock = (spec?.spec ?? {}) as Record; + const caps = (specBlock?.capabilities ?? {}) as Record; + const codeCaps = Array.isArray(caps?.code) ? (caps.code as { id?: string }[]) : []; + const toolIds = codeCaps.map((t) => t?.id).filter((x): x is string => Boolean(x)); + const all = walkTs(scaffoldDir); + const srcFiles = all.filter((f) => !/\.test\.ts$/.test(f.path)); + const testFiles = all.filter((f) => /\.test\.ts$/.test(f.path)); + return computeCoverage(toolIds, srcFiles, testFiles, []); +} + +// ── CLI ───────────────────────────────────────────────────────────────────────── +function runCli(argv: string[]): number { + const args = argv.slice(2).filter((a) => !a.startsWith("--")); + const [specPath, scaffoldDir] = args; + if (!specPath || !scaffoldDir) { + process.stderr.write( + "Usage: scripts/cli/run.sh scripts/verify/spec-impl-coverage.ts \n" + + "Asserts every spec.capabilities.code[].id has an `// @implements ` module + a test.\n" + + "Exit 0 = all covered; exit 1 = an uncovered code capability (STEER).\n", + ); + return 1; + } + let result: CoverageResult; + try { + result = coverageForScaffold(specPath, scaffoldDir); + } catch (err) { + process.stderr.write(`Error reading ${specPath}: ${String(err)}\n`); + return 1; + } + console.info("tool-id module test covered"); + console.info("───────────────── ────────────────────────────── ─────────────────── ───────"); + for (const e of result.entries) { + const mod = e.module ? path.basename(e.module) : "—"; + const tst = e.test ? path.basename(e.test) : "—"; + console.info( + `${e.id.padEnd(17)} ${mod.padEnd(30)} ${tst.padEnd(19)} ${e.covered ? "✓" : "✗"}` + + (e.reason ? `\n └─ ${e.reason}` : ""), + ); + } + for (const d of result.danglingBackedBy) + console.info(`✗ dangling job.backed_by → "${d}" is not a declared code tool`); + if (result.ok) { + console.info(`[coverage] PASS — all ${result.entries.length} code tool(s) implemented + tested.`); + return 0; + } + const missing = result.entries.filter((e) => !e.covered).map((e) => e.id); + console.info( + `[coverage] STEER — uncovered: ${missing.join(", ") || "(none)"}` + + (result.danglingBackedBy.length ? ` · dangling: ${result.danglingBackedBy.join(", ")}` : ""), + ); + return 1; +} + +if (isEntrypoint(import.meta.url)) process.exit(runCli(process.argv)); diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/README.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/README.md new file mode 100644 index 00000000..eb240768 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/README.md @@ -0,0 +1,192 @@ +# mutagent-diagnostics — Skill Bundle + +> **Audience: skill maintainers working inside this bundle.** +> For the end-user / install guide see the package-level +> [`mutagent-system/mutagent-diagnostics/README.md`](../../../README.md). + +--- + +## What lives here + +This directory is the skill bundle — the self-contained artifact published to GitHub Packages +as `@mutagent/diagnostics`. It is structured as an [agentskills.io](https://agentskills.io) +compliant skill, installable into any Claude Code, Codex, Cursor, or OpenCode session via +`pnpx @mutagent/diagnostics init`. + +The canonical spec is `SKILL.md` (§0-§9, incl. §3.1 gold-standard report shape + §3.2 structured +contract mode). Everything else in this bundle is referenced from it. + +--- + +## Bundle layout + +``` +mutagent-diagnostics/ ← this directory +│ +├── SKILL.md ← operational contract §0-§9 (≤500 lines per PR-007) +├── .npmignore ← strips internal/ + *.test.ts on publish +│ +├── scripts/ ← Type A: pure bun scripts (deterministic, no agent reasoning) +│ ├── tier0-scan.ts ← static scan — free cost gate before LLM (PR-001) +│ ├── tier0-scan.test.ts ← unit tests [stripped on publish] +│ ├── slicer.ts ← dynamic-cluster slicing, cap-of-5 (PR-005, PR-017) +│ ├── stale-detector.ts ← hash compare before any write (PR-011) +│ ├── cli/ +│ │ ├── init.ts ← pnpx entrypoint + runtime detection (PR-021) +│ │ ├── install-agents.ts ← idempotent agent .md installer +│ │ └── run.sh ← bun → pnpm → npm → npx fallback (R-014-A) +│ ├── config/ +│ │ ├── schema.ts ← TypeBox schema — single source of truth (PR-009) +│ │ ├── load.ts ← YAML parse + env-ref resolution +│ │ └── validate.ts ← typed validation errors +│ ├── fetch/ +│ │ ├── langfuse.ts ← Langfuse trace fetch + filter +│ │ ├── claude-code-transcripts.sh ← transcript discovery (bash, R-014-A) +│ │ └── assemble-meta.ts ← meta-context assembly +│ ├── normalize/ +│ │ ├── trace.ts ← canonical types + EntityContext/SizedText/ToolInventoryEntry/Assumption (Wave-5) +│ │ └── platforms/ ← per-platform shape mappers (PR-016) +│ │ └── entity-context.ts ← shared deterministic EntityContext extractors (Wave-5 R1.7, no LLM) +│ ├── enrich/ +│ │ └── build-render-input.ts ← Wave-5 R1.4 enricher → fully-populated RenderInput (Step 8.5, fail-loud) +│ ├── contract/ +│ │ └── types.ts ← TypeBox SelfDiagnosisContract schema (Wave-4 structured-report mode) +│ ├── report/ +│ │ ├── render.ts ← enriched RenderInput → gold-standard multi-tab HTML (PR-014/PR-029) +│ │ └── persist-selections.ts ← persist operator copy-back selections from the HITL gate +│ ├── lint/ +│ │ └── template-inline-js.ts ← R-007-B: reject TS in HTML + + diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/README.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/README.md new file mode 100644 index 00000000..63e34e2a --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/README.md @@ -0,0 +1,27 @@ +# Bundled shared templates (self-contained) + +These install-time-copy templates were historically distributed via the peer +package `@mutagent/templates`. As of the npm public release of +`@mutagent/diagnostics`, they are **bundled directly into this package** so the +skill ships fully self-contained — `init` works offline from the package alone, +with **no peer-install and no dependency on `@mutagent/templates`**. + +| File | Purpose | +|------|---------| +| `self-diagnosis-contract.v0.1.0.yaml.tpl` | Frozen v0.1.0 contract schema a target repo declares to opt into structured 10-category reports | +| `spec.yaml.tpl` | afkloop goal + termination-gate spec scaffold | +| `team.yaml.tpl` | actor/verifier team scaffold | +| `iter-N-handover.md.tpl` | per-iteration dispatch-brief scaffold | +| `wave-N-dashboard.html.tpl` | operator-facing wave dashboard scaffold | + +## Resolution + +Runtime code locates this directory via `sharedTemplatesDir()` in +`scripts/cli/shared-templates.ts` (canonical path +`/assets/templates/shared/`), mirroring how `report/render.ts` +resolves `assets/templates/report.html.tpl`. Because the directory lives inside +the shipped skill tree, the cross-platform installer (`init`) copies it as part +of the normal skill-directory copy — no separate fetch step is required. + +> Tier-2 runtime asset. Ships with the package. Do NOT move under `internal/` +> (that path is stripped on publish). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl new file mode 100644 index 00000000..ac835bc2 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/iter-N-handover.md.tpl @@ -0,0 +1,125 @@ +# iter-{{N}}-handover.md — {{wave_id}} {{phase_label}} + +> **MANDATORY PRE-READ** for Actor + Verifier of `{{wave_id}}-iter-{{N}}`. +> Pre-staged during autonomous burn. Read in entirety BEFORE editing. + +--- + +## §0 — One-line summary + +{{summary_one_liner}} + +> **Predecessor**: {{predecessor_ref}}. + +--- + +## §1 — Environment + Hard constraints + +| Setting | Value | +|---|---| +| **Worktree path** | `{{worktree_path}}` | +| **Branch** | `{{branch}}` | +| **Trunk PR** | {{trunk_pr_ref}} — OPEN, do NOT merge to main | +| **Baseline HEAD** | `{{baseline_sha}}` ({{baseline_note}}) | + +**Hard constraints (UNCHANGED):** +- ❌ Do NOT merge to `main`. +- ❌ Do NOT touch `.github/workflows/`, `Dockerfile`, `tsconfig*.json`, `bunfig.toml`, root checkout. +- ❌ Do NOT skip pre-commit hooks (`--no-verify` FORBIDDEN per `feedback_correctness_discipline`). +- ❌ Do NOT add `process.env.DISABLE_*` / `ENABLE_*` rollback knobs. +{{additional_hard_constraints}} + +--- + +## §2 — In-scope work + +{{in_scope_table_or_prose}} + +--- + +## §3 — Cross-dependency callout + +{{cross_dep_callout}} + +--- + +## §4 — Within-phase ordering (suggested) + +{{ordering_steps}} + +--- + +## §5 — Acceptance commands + +```bash +{{acceptance_commands}} +``` + +--- + +## §6 — Final-Status PR comment (template Actor fills + posts) + +```markdown +## 🏁 {{phase_label}} — Final Status + +### Decisions table + +| Decision | Choice | WHY | +|---|---|---| +{{decisions_table_rows}} + +### Commit chain + +{{commit_chain_summary}} + +### Status + +{{final_status_summary}} + +**DO NOT merge {{trunk_pr_ref}} to main** until operator green-lights. +``` + +--- + +## §7 — Verifier-only ground-truth probes + +```bash +{{verifier_probes}} +``` + +--- + +## §8 — Known gotchas + +{{known_gotchas_table}} + +### Carried forward (from prior iterations) + +{{carried_forward_gotchas}} + +--- + +## §9 — Memory rules in force + +{{memory_rules_list}} + +--- + +## §10 — Exit criteria (PASS) + +All of: +{{exit_criteria_bullets}} + +On PASS → {{on_pass_next_step}}. + +--- + +## §11 — Failure modes + +| Symptom | Verdict | +|---|---| +{{failure_modes_table_rows}} + +--- + +End of iter-{{N}}-handover.md. After this iteration: {{post_iter_next_action}}. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl new file mode 100644 index 00000000..6bc9a766 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/self-diagnosis-contract.v0.1.0.yaml.tpl @@ -0,0 +1,234 @@ +# self-diagnosis-contract.yaml — FROZEN SCHEMA v0.1.0 +# ═════════════════════════════════════════════════════════════════════════════ +# This file is the inter-skill CONTRACT. Any skill that wants STRUCTURED +# (rather than open-ended) diagnostic reports about its own behavior ships a +# populated copy of this template at: +# +# /self-diagnosis-contract.yaml +# +# A diagnostic skill (any tool that ingests traces and emits findings) MAY +# look for this file when targeting . If present → structured report +# per declared criteria. If absent → open-ended pattern-match (status quo). +# +# Schema is FROZEN at v0.1.0. Mid-flight changes FORBIDDEN. New versions ship +# as NEW filenames (self-diagnosis-contract.v0.2.0.yaml.tpl). +# ═════════════════════════════════════════════════════════════════════════════ + +schema_version: "0.1.0" + +# ─── Subject identification ─────────────────────────────────────────────────── +skill: + name: "{{skill_name}}" # e.g. mutagent-some-skill (no leading @) + version: "{{skill_version}}" # semver + class: "{{skill_class}}" # one of: pure-procedural | orchestrator | tool-skill | meta-skill + +# ─── 10-CATEGORY SUCCESS CRITERIA (Hybrid decomposition · operator-locked 2026-05-31) ── +# +# The 10 categories cover: Operational / Onboarding / Behavioral / HITL / +# Output / Methodology / Tier-performance / Source-platform health / +# Target-platform health / Maintenance. +# +# Each category contains a `criteria[]` array. Each criterion has: +# id — kebab-case stable identifier +# statement — binary observable assertion ("X happens") +# evidence_source — one of: trace | commit | cmd-output | file:line | screenshot +# +# Producer skills evaluate per-criterion against the target's trace and emit +# a result per criterion: pass | fail | not-applicable | pending. +# +# Skills SHOULD declare ≥1 criterion per relevant category and MAY skip +# categories that don't apply to their class (e.g. tool-skill class has no +# HITL gates → leave category present with `criteria: []` and a `notes:` line). +# ───────────────────────────────────────────────────────────────────────────── +success_criteria: + + # ──── 1. OPERATIONAL ──────────────────────────────────────────────────────── + # Install / invoke / runtime / exit hygiene. + - category: operational + notes: "install / invoke / runtime detection / exit codes" + criteria: + - id: "{{op_criterion_1_id}}" + statement: "{{op_criterion_1_statement}}" + evidence_source: "{{op_criterion_1_evidence_source}}" + # Append additional operational criteria as needed. + + # ──── 2. ONBOARDING ───────────────────────────────────────────────────────── + # First-time UX / platform detection / config persistence. + - category: onboarding + notes: "first-invocation routing / platform detect / config persist" + criteria: + - id: "{{on_criterion_1_id}}" + statement: "{{on_criterion_1_statement}}" + evidence_source: "{{on_criterion_1_evidence_source}}" + + # ──── 3. BEHAVIORAL / AGENT HANDOFFS ─────────────────────────────────────── + # Dispatch → return / cap-of-5 fan-out / orphan check / sub-agent contracts. + - category: behavioral + notes: "agent dispatch + return + cap-of-5 + orphan check" + criteria: + - id: "{{bh_criterion_1_id}}" + statement: "{{bh_criterion_1_statement}}" + evidence_source: "{{bh_criterion_1_evidence_source}}" + + # ──── 4. HITL GATES ───────────────────────────────────────────────────────── + # AskUserQuestion fires correctly + clipboard handoff (or platform-fallback). + - category: hitl + notes: "AskUserQuestion fires + clipboard handoff + chat-fallback works" + criteria: + - id: "{{hi_criterion_1_id}}" + statement: "{{hi_criterion_1_statement}}" + evidence_source: "{{hi_criterion_1_evidence_source}}" + + # ──── 5. OUTPUT ───────────────────────────────────────────────────────────── + # Report schema / template-stamp discipline / payload contracts. + - category: output + notes: "output artifacts conform to declared schema; template-stamp not procedural" + criteria: + - id: "{{os_criterion_1_id}}" + statement: "{{os_criterion_1_statement}}" + evidence_source: "{{os_criterion_1_evidence_source}}" + + # ──── 6. METHODOLOGY HYGIENE ─────────────────────────────────────────────── + # Step 0 census, assumption enumeration, evidence grounding, recursive whys. + - category: methodology + notes: "Step 0 census + assumptions + evidence-grounded findings + recursive whys" + criteria: + - id: "{{me_criterion_1_id}}" + statement: "{{me_criterion_1_statement}}" + evidence_source: "{{me_criterion_1_evidence_source}}" + + # ──── 7. TIER / PERFORMANCE ──────────────────────────────────────────────── + # Tier 0 → LLM gating / budgets / cap-of-5 / relative thresholds (not hardcoded). + - category: tier-performance + notes: "Tier 0 scan before LLM + budgets + relative thresholds (no hardcoded ms/token)" + criteria: + - id: "{{tp_criterion_1_id}}" + statement: "{{tp_criterion_1_statement}}" + evidence_source: "{{tp_criterion_1_evidence_source}}" + + # ──── 8. SOURCE-PLATFORM HEALTH ──────────────────────────────────────────── + # For skills that consume external sources (traces, transcripts, JSONL etc). + - category: source-platform + notes: "if skill ingests sources: each source primitive normalizes correctly" + criteria: + - id: "{{sp_criterion_1_id}}" + statement: "{{sp_criterion_1_statement}}" + evidence_source: "{{sp_criterion_1_evidence_source}}" + + # ──── 9. TARGET-PLATFORM HEALTH ──────────────────────────────────────────── + # For skills that emit changes to external targets (local-agent .md / cloud REST etc). + - category: target-platform + notes: "if skill applies changes: each target adapter behaves per contract" + criteria: + - id: "{{tg_criterion_1_id}}" + statement: "{{tg_criterion_1_statement}}" + evidence_source: "{{tg_criterion_1_evidence_source}}" + + # ──── 10. MAINTENANCE ─────────────────────────────────────────────────────── + # doctor / self-diagnosis / audit emit / version-pin / SKILL.md frontmatter integrity. + - category: maintenance + notes: "doctor.ts + audit emit + version pinned + frontmatter intact" + criteria: + - id: "{{mt_criterion_1_id}}" + statement: "{{mt_criterion_1_statement}}" + evidence_source: "{{mt_criterion_1_evidence_source}}" + +# ─── SCENARIO MATRIX ───────────────────────────────────────────────────────── +# Operator-runnable scenarios that exercise the skill end-to-end. A diagnostic +# tool consuming this contract attempts to MATCH trace evidence against each +# scenario's trigger pattern, then evaluates acceptance_gate. +# +# Each scenario: +# id — kebab-case unique id (e.g. s1-happy-path, s2-error-edge) +# trigger — what kicks the scenario off (CLI invocation / API call / event) +# expected — observable end-state (one-line description) +# acceptance_gate — concrete verification: command exit / metric / predicate / llm-judge +# ───────────────────────────────────────────────────────────────────────────── +scenarios: + - id: "{{scenario_1_id}}" + trigger: + type: "{{scenario_1_trigger_type}}" # cli | api | event | chat + payload: "{{scenario_1_trigger_payload}}" # literal invocation string + expected: "{{scenario_1_expected}}" # 1-line observable end-state + acceptance_gate: + gate_type: "{{scenario_1_gate_type}}" # command-exit | metric-threshold | predicate | llm-judge + gate_spec: "{{scenario_1_gate_spec}}" # type-specific specification + + # Append additional scenarios. Recommended ≥3 (happy / edge / failure-mode). + +# ─── TRAJECTORY LOG FORMAT ─────────────────────────────────────────────────── +# Append-only log of captured invocations of THIS skill, in a shape that +# downstream diagnostic tools can ingest without transformation. +# +# Each trajectory entry: +# invocation_id — UUID stamped at invocation time +# captured_at — ISO8601 timestamp +# scenario_id — matches a scenarios[].id above OR "freeform" +# trace_refs — pointers to the underlying trace evidence +# diagnostics_ingestable — true = no transformation needed; false = needs adapter +# summary — 1-sentence what happened +# findings_count_by_audience — counts per PRODUCT/META/CORE audience tag +# ───────────────────────────────────────────────────────────────────────────── +trajectory_log_format: + schema: + invocation_id: "string (uuid v4)" + captured_at: "string (ISO8601)" + scenario_id: "string (matches scenarios[].id) | 'freeform'" + trace_refs: + langfuse_session: "string | null" + playwright_trace: "string (path) | null" + claude_code_session: "string (jsonl path) | null" + otel_span: "string (span id) | null" + diagnostics_ingestable: "boolean" + summary: "string (≤1 sentence)" + findings_count_by_audience: + PRODUCT: "integer ≥0" + META: "integer ≥0" + CORE: "integer ≥0" + + # Default landing path. Skill may override to relocate within its source tree + # but the SHAPE above is fixed (so diagnostic tools can ingest without + # per-skill adapters). + default_landing_path: "/trajectory-log.yaml" + +# ─── EVIDENCE LANDING PATHS ───────────────────────────────────────────────── +# Where the producer skill should write structured artifacts when emitting +# a report against this contract. +# ───────────────────────────────────────────────────────────────────────────── +evidence_landing_paths: + test_report_yaml: "{{landing_test_report_yaml}}" # default: /test-report.yaml + trajectory_log_append_to: "{{landing_trajectory_log}}" # default: /trajectory-log.yaml + llm_judge_results_dir: "{{landing_llm_judge_dir}}" # default: /llm-judge-evals/ + +# ─── AUDIENCE TAG HINTS (optional) ────────────────────────────────────────── +# Guidance for producer skills' audience-tag classifiers (PRODUCT / META / CORE). +# Skill can supply patterns matching its own typical failure origins to help +# the classifier route findings correctly without operator override. +# ───────────────────────────────────────────────────────────────────────────── +audience_tag_hints: + finding_patterns: + - pattern: "{{audience_hint_1_pattern}}" # regex on failureOrigin.where or .what + default_audience: "{{audience_hint_1_audience}}" # one of: PRODUCT | META | CORE + +# ═════════════════════════════════════════════════════════════════════════════ +# Schema-freeze invariants (DO NOT VIOLATE) +# ═════════════════════════════════════════════════════════════════════════════ +# 1. The 10 categories above are the COMPLETE canonical set for v0.1.0. No +# skill may add or rename categories within this schema version. New +# categories require a versioned bump (v0.2.0 — new file). +# +# 2. Each criterion's `evidence_source` MUST be one of the 5 allowed values: +# trace | commit | cmd-output | file:line | screenshot. No free-form +# evidence sources. +# +# 3. Each scenario's `gate_type` MUST be one of the 4 allowed values: +# command-exit | metric-threshold | predicate | llm-judge. +# +# 4. trajectory_log_format.schema is the SHAPE producer skills must emit when +# appending to a target's trajectory log. Adding fields is forbidden +# within this version (forward-compat only via versioned bump). +# +# 5. audience tags are the 3 from the established taxonomy: PRODUCT (user- +# visible behavior), META (methodology / discipline observations), CORE +# (runtime engine / scripts / sub-agents). +# ═════════════════════════════════════════════════════════════════════════════ diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl new file mode 100644 index 00000000..4d6441f9 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/spec.yaml.tpl @@ -0,0 +1,152 @@ +# spec.yaml — afkloop spec for {{wave_id}} +# Template extracted from afkloop-mdiag-w2 spec.yaml (proven across 5 iterations). +# Consumer renderer fills {{...}} placeholders at install / dispatch time. + +afkloop_id: {{wave_id}} +intent: | + {{wave_intent_paragraph}} + +scope: + files: + {{#each scope_files}} + - {{path_glob}} + {{/each}} + repos: [{{repos_csv}}] + worktree_path: {{worktree_path}} + branch: {{branch}} + pr_trunk: {{pr_trunk_number}} + +goal_condition: + type: observable + predicate: | + {{goal_predicate}} + probe_interval: {{probe_interval}} + +termination_gates: + max_iterations: {{max_iterations}} + max_wallclock_minutes: {{max_wallclock_minutes}} + max_consecutive_failures: {{max_consecutive_failures}} + max_tokens_spent: {{max_tokens_spent}} + on_scope_creep: abort + on_phase_complete: {{on_phase_complete_action}} + +# ──────────────────────────────────────────────────────────────────────────── +# DISPATCH GATE — hard pre-spawn check +# ──────────────────────────────────────────────────────────────────────────── +# NO TeamCreate, NO Agent() spawn may proceed for iteration N without +# operator-approved review artifacts present + an approval signal file on +# disk. iter-1 of each wave MAY be grandfathered per `precedent_record`. +dispatch_gate: + scope: {{dispatch_gate_scope}} + required_artifacts_before_dispatch: + {{#each required_dashboard_artifacts}} + - path: {{path}} + semantics: {{semantics}} + {{/each}} + required_signal_file: + path: {{approval_flag_path_template}} + semantics: | + Created ONLY by operator via clipboard-export from the iter-N dashboard + lockin block (LOCK / REVISE / HOLD / DROP radios + decision textarea). + Orchestrator MUST verify file exists + has non-zero size before any + Agent() / TeamCreate call. + enforcement: + mode: refuse_spawn_with_message + error_message: | + Iteration requires operator-approved review artifacts + the + iter--approved.flag signal file. Dispatch REFUSED. Operator must + review the rendered artifacts and clipboard-export their decision. + precedent_record: + {{#each precedent_records}} + {{iter_label}}: | + {{precedent_text}} + {{/each}} + +iteration_contract: + inputs: + {{#each iteration_inputs}} + - {{description}} + {{/each}} + one_tick_does: | + {{one_tick_does_paragraph}} + + deliverables: + code_artifacts: + {{#each code_artifacts}} + - "{{artifact}}" + {{/each}} + design_review_artifacts: + {{#each design_review_artifacts}} + {{key}}: + path: {{path}} + purpose: | + {{purpose}} + {{/each}} + +agent_team: + actor: + subagent_type: {{actor_subagent_type}} + prompt_template: | + MANDATORY PRE-READ: + cat {{handover_path_template}} + {{actor_prompt_body}} + verifier: + subagent_type: {{verifier_subagent_type}} + role: {{verifier_role}} + watches: + {{#each verifier_watch_sources}} + - {{source}} + {{/each}} + can_inject: [course-correct, abort, escalate-to-user] + +live_steering_protocol: + mode: checkpoint + checkpoint_triggers: + {{#each checkpoint_triggers}} + - {{trigger}} + {{/each}} + +observability: + tasklist_prefix: "[{{wave_id}}]" + per_iter_log: {{per_iter_log_path_template}} + per_iter_handover: {{per_iter_handover_path_template}} + views_anchor: + {{#each views_anchors}} + {{key}}: {{path}} + {{/each}} + +exit_behavior: + on_success: | + {{on_success_text}} + on_gate_hit: | + {{on_gate_hit_text}} + on_user_interrupt: | + {{on_user_interrupt_text}} + on_phase_complete: | + {{on_phase_complete_text}} + +skill_handover: + parent_skills: + {{#each parent_skills}} + - {{skill_name}} + {{/each}} + inline_files: + # Pulled into iter-N-handover.md verbatim at Phase 1.5 + {{#each inline_files}} + - {{path}} + {{/each}} + handover_doc: {{handover_doc_path_template}} + +prior_session_artifacts: + {{#each prior_session_artifacts}} + - path: {{path}} + description: {{description}} + {{/each}} + +known_gotchas: + {{#each known_gotchas}} + - id: {{id}} + description: {{description}} + workaround: {{workaround}} + source: {{source}} + {{/each}} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl new file mode 100644 index 00000000..4c71e835 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/team.yaml.tpl @@ -0,0 +1,127 @@ +# team.yaml — afkloop team for {{wave_id}} +# Template extracted from afkloop-mdiag-w2 team.yaml (proven across 5 iterations). +# Consumer renderer fills {{...}} placeholders at install / dispatch time. + +team: + name: {{wave_id}}-iter-{N} + lifecycle: per-iteration # TeamCreate at tick start, TeamDelete at tick end + + # ────────────────────────────────────────────────────────────────────── + # PRE-SPAWN GATE — see spec.yaml dispatch_gate for full rationale + # ────────────────────────────────────────────────────────────────────── + pre_spawn_gate: + skip_for_iterations: [{{grandfather_iterations_csv}}] + required_files_exist: + {{#each required_review_files}} + - {{path_template}} + {{/each}} + required_signal_file: + path: {{approval_flag_path_template}} + check: test -s + on_failure: | + REFUSE TeamCreate AND any Agent() spawn for iter-{N}. Print error, + surface paths to operator, await re-invocation after approval. + ABORT cascades up to the parent orchestrator — do NOT silently + proceed. Do NOT improvise around the gate. + + actor: + type: {{actor_agent_type}} + scope: + {{#each actor_scope_globs}} + - {{glob}} + {{/each}} + forbidden_paths: + - .github/workflows/** # infra changes deferred to end-of-wave PR + - Dockerfile** + - tsconfig*.json + - bunfig.toml + - .claude/settings.local.json # operator-owned on root + {{#each additional_forbidden_paths}} + - {{glob}} + {{/each}} + prompt: | + You are the Actor for {{wave_id}} iteration {N}{{actor_phase_suffix}}. + + MANDATORY PRE-READ: + cat {{handover_path_template}} + + This handover contains: + - The {{phase_descriptor}} scope (your task) + - Skill operational contracts (relevant SKILL.md + workflow refs) inlined + - Per-remedy acceptance commands + - Known gotchas + - Drift from prior iterations + rediscovery promotions + - Scope envelope + forbidden paths + + Internalize handover BEFORE editing. Then: + 1. Implement remedies in handover-specified order (within-phase deps) + 2. ONE commit per remedy, message prefixed with remedy ID + 3. Run acceptance commands LOCALLY before pushing + 4. Push to {{branch}} + 5. Emit checkpoints at: plan internalized, first commit pushed, all commits done, acceptance run + + Hard constraints: + - Do NOT merge to main + - Do NOT touch forbidden_paths + - Do NOT skip pre-commit hooks (--no-verify FORBIDDEN per feedback_correctness_discipline) + - On Verifier SendMessage with binding steering — comply + + {{additional_actor_constraints}} + + On phase complete: post PR Final-Status comment per feedback_pr_final_status_comment.md. + + verifier: + type: {{verifier_agent_type}} + role: live-steering-observer + handover-saturation-auditor + ground_truth_sources: + {{#each verifier_ground_truth_sources}} + - {{source}} + {{/each}} + prompt: | + You are the Verifier for {{wave_id}} iteration {N}. + You do NOT execute the implementation. + + VERIFIER CONTEXT INVERSION — you receive the SUPERSET of Actor's brief: + - Full iter-{N}-handover.md (same as Actor) + - All skill operational contracts (SKILL.md + workflow refs) + - prior_session_artifacts catalog (so you can cross-reference) + - known_gotchas catalog (so you can pre-empt rediscovery) + - Verifier-only ground-truth probes (do NOT run as Actor's behalf) + + GOAL (this iteration): {{verifier_goal_summary}}. + Hard gates: scope envelope, forbidden_paths, no-merge-to-main, no --no-verify. + + {{additional_verifier_invariants}} + + Monitor Actor's task output. On each checkpoint: + - Read Actor's stated plan + diff so far + - Cross-check against handover-inlined contracts + - Check scope compliance (in scope + not forbidden) + - Check drift from THIS phase's remedy IDs + - Decide: PROCEED (silent) | STEER (SendMessage Actor) | ABORT (SendMessage Orchestrator) + + Steering messages must be SPECIFIC + REASONED + MINIMAL. + Drift in ≥3 dimensions = ABORT not STEER (per anti-pattern table). + + On iteration end, list REDISCOVERY EVENTS (Actor probed --help / introspection + / trial-and-error that should have been in handover). These get promoted into + iter-{N+1}-handover.md known_gotchas. Loop converges toward zero rediscovery + per iteration. + + Final verdict: PASS | RETRY | ABORT. + On PASS — confirm phase Final-Status comment is accurate before authorizing + pause-for-dogfood. + +per_phase_overrides: + {{#each per_phase_overrides}} + {{iter_label}}: + phase: {{phase_letter}} + remedies: [{{remedies_csv}}] + risk_pill: {{risk_pill_class}} + estimated_hours: {{estimated_hours}} + acceptance: + {{#each acceptance_commands}} + - {{cmd}} + {{/each}} + {{optional_phase_notes}} + {{/each}} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl new file mode 100644 index 00000000..77726f42 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/templates/shared/wave-N-dashboard.html.tpl @@ -0,0 +1,1712 @@ + + + + + +MUTAGENT — {{SKILL_DISPLAY_NAME}} · Wave-{{WAVE_N}} Dashboard + + + + + + + + +
+ [INTERNAL DEV TEMPLATE — Design Tier 1] — NOT SHIPPED TO END USERS  ·  internal/templates/review/wave-dashboard-template.html +
+ + + + + + + +
+ + + +
+
+
Wave
+
W{{WAVE_N}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + +
+ + + + +
+
+

Wave-{{WAVE_N}} — WIP Board

+

Drag (mentally) cards as work moves between columns. Add .kcard.now to highlight the active card.

+ +
+
+
📦 Backlog 0
+ +
+
+
⚙ In-Flight 0
+ +
+
+
🐕 Dogfood-Pending 0
+
+
+
✓ Verified 0
+
+
+
🚀 Shipped 0
+
+
+ +
Status key: Backlog (not started) → In-Flight (dev) → Dogfood-Pending (shipped, awaits real-world trigger) → Verified (evidence collected) → Shipped (merged/closed).
+
+ + +
+

Wave Summary

+ +

+ + + + + + + + + +
PhasePRStatusLandedNotes
Phase A⚪ backlog
Phase B⚪ backlog
Phase C⚪ backlog
Phase D⚪ backlog
Phase E⚪ backlog
+
+
+ + +
+
+

Tree Changelog — what moves between iterations

+

Fill from git diff --stat origin/main...HEAD + per-phase file list. Use <b> for key files, <i> for dirs, <em> for comments.

+ + +
+ +
How to fill: Run git diff --stat origin/main...HEAD in the worktree. Copy the output here. Use <b> on the most-changed files. Add <em> inline comments explaining WHY each file was touched.
+
+
+ + +
+ +
+
+
Phase A
+
+
+ ⚪ backlog + + +
+
+ +
+

🎯 Goal

+

+
+ +
Voice-stamp T?: ""
+ +
+

📋 Scope of work

+
    +
  1. :
  2. +
  3. :
  4. +
+
Constraint:
+
+ +
+

📂 Files touched

+ + + + + +
FileActionNotes
NEW · EDIT · DELETE
+
+ +
+

✅ Acceptance criteria

+
    +
  • +
  • +
+
+ +
+
Dependencies
+
Risks
+
Voice-stamps
+
PR scope
+
+ +
+
Phase A — approve to dispatch
+
+ + + + +
+ +
+
+
+ + +
+
+
+
Phase B
+
+
+ ⚪ backlog + +
+
+

🎯 Goal

+
Voice-stamp T?: ""
+
+

📋 Scope

+
  1. :
+
+
+

📂 Files

+ + +
FileActionNotes
EDIT
+
+

✅ Acceptance

+
+
Dependencies
Phase A
+
Risks
+
Voice-stamps
+
PR scope
1 PR
+
+
+
Phase B — approve to dispatch
+
+ + + + +
+ +
+
+
+ + +
+
+
+
Phase C
+
+
⚪ backlog
+
+

🎯 Goal

+
+

📋 Scope

+
  1. :
+
+

✅ Acceptance

+
+
Phase C — approve to dispatch
+
+ + + + +
+ +
+
+
+ + +
+
+
+
Phase D
+
+
⚪ backlog
+
+

🎯 Goal

+
+

📋 Scope

+
  1. :
+
+

✅ Acceptance

+
+
Phase D — approve to dispatch
+
+ + + + +
+ +
+
+
+ + +
+
+
+
Phase E
+
+
+ ⚪ backlog + arch +
+
+

🎯 Goal

+
+

📋 Scope

+
  1. :
+
+

✅ Acceptance

+
+
Phase E / Final — squash-merge trigger
+
+ + + +
+ +
+
+
+ + +
+
+

Drift Audit — spec vs implementation gaps

+

List findings where implementation drifted from the design. Each item has an ID, body, and resolution plan.

+ + +
+
DRIFT-01 ·
+
+
+
+ +
How to fill: After each phase PR lands, do a diff-to-spec pass (compare files-touched vs SKILL.md §4 BoM + §5 agents + §3 architecture). Log every mismatch here. Resolved items get .oq.resolved-oq treatment when fixed.
+
+
+ + +
+
+

Open Questions

+

Decisions pending operator input or additional evidence. Resolved items get a green border; leave the OQ for audit trail.

+ + +
+
OQ-01 · open
+
+
+ +
How to fill: Add an OQ whenever a decision fork comes up during implementation. Reference by ID in phase cards. Once resolved, flip class to resolved-oq and fill in resolution body.
+
+
+ + +
+
+

Lockin / Wave Decisions

+

Summary of all wave-level decisions locked in so far. Use the "Copy Decisions" button to export as markdown for the orchestrator.

+ + + + + + + +
IDDecisionChoiceRationale
DEC-01
DEC-02
+ + +
+
Wave {{WAVE_N}} — final wave-level decision
+
+ + + +
+ +
+
+
+ +
+ + + +
+ + + + +
+
+

① Setup Detection (§0)

+

+ + +

+ + + + + +
Fill from: SKILL.md §0 + references/workflows/onboarding.md. Replace this rationale block with actual design decision context.
+
+
+ + +
+
+

② Triggers (§1)

+

+ + + + + + + +
Trigger phraseMaps toNotes
+
Fill from: SKILL.md §1. Add every trigger phrase with its canonical invocation form.
+
+
+ + +
+
+

③ Architecture Overview (§3)

+

+ + + + + + + + + +
StageRuns inOwnerNotes
+
Fill from: SKILL.md §3 + references/reference.md.
+
+
+ + +
+
+

④ Bill of Materials — scripts/ (§4)

+

+ + + + + + + + + +
ScriptPurposeInvoked by
scripts/cli/run.sh
scripts/slicer.tsrun.sh
scripts/tier0/tier0-scan.tsrun.sh
scripts/report/render.tsrun.sh
+
Fill from: SKILL.md §4. List every entry-point script + sub-scripts. Include the run.sh dispatch contract as a <pre> block.
+
+
+ + +
+
+

⑤ Agents — assets/agents/ (§5)

+

+ + + + + + + +
AgentClassDispatched byPurpose
diagnostics-analyzer.mdrun.sh
diagnostics-apply-worker.mdrun.sh
+
Fill from: SKILL.md §5 + assets/agents/ directory. Document capability constraints (what agents can/cannot do) and rationale.
+
+
+ + +
+
+

⑥ References — references/ (§6)

+

+ +
+
+
+

⑦ Config (§7)

+

+ + + + + + +
FieldTypeDefaultPurpose
+
Source of truth: scripts/config/schema.ts. The config reference doc (references/config.md) must match the schema. The template (assets/templates/config.yaml.tpl) must match both.
+
+
+ + +
+
+

⑧ Design Principles (§8) ⭐

+

PR-001 through PR-023 are current (source of truth: references/principles.md). PR-024+ are proposed additions from iter-12 review — pending formal write-up + adoption.

+ +
Proposed for iter-12: PR-024 (portability) · PR-025 (renderer-smoke-test) · PR-026 (cross-platform install). See the principle.proposed cards below. These are NOT yet in references/principles.md.
+ + + + +

Current Principles — PR-001 through PR-023

+ +
+
PR-001
+
+
+
+ +
+
PR-002
+
+
+
+ +
+
PR-003
+
+
+
+ +
+
PR-004
+
+
+
+ +
+
PR-005
+
+
+
+ +
+
PR-006
+
+
+
+ +
+
PR-007
+
+
+
+ +
+
PR-008
+
+
+
+ +
+
PR-009
+
+
+
+ +
+
PR-010
+
+
+
+ +
+
PR-011
+
+
+
+ +
+
PR-012
+
+
+
+ +
+
PR-013
+
+
+
+ +
+
PR-014
+
+
+
+ +
+
PR-015
+
+
+
+ +
+
PR-016
+
+
+
+ +
+
PR-017
+
+
+
+ +
+
PR-018
+
+
+
+ +
+
PR-019
+
No inline Python heredocs
+
Shell scripts MUST NOT embed Python via heredoc. Extract to scripts/*.ts and invoke via bun run. Violations caught by PR-019 lint gate.
+
+ +
+
PR-020
+
+
+
+ +
+
PR-021
+
+
+
+ +
+
PR-022
+
+
+
+ +
+
PR-023
+
+
+
+ + +

Proposed Principles — PR-024+ (iter-12 proposal, not yet adopted)

+
Note: These are hypotheses surfaced during Wave-{{WAVE_N}} review. They need a formal write-up + operator approval before being written to references/principles.md. Audit Matrix tab §8 cross-links here.
+ +
+
PR-024 · proposed
+
Portability — no hard-coded absolute paths in scripts
+
Scripts MUST NOT hard-code absolute paths. All paths are derived from runtime variables ($SKILL_ROOT, $CWD, etc.) or config entries. Enables moving skill between machines and clones without edits.
+
+ +
+
PR-025 · proposed
+
Renderer smoke-test — report.html.tpl must have a companion smoke test
+
Any change to assets/templates/report.html.tpl requires a companion smoke test that renders the template with minimal fixture data and asserts no JS errors + expected heading text. Prevents silent template regressions.
+
+ +
+
PR-026 · proposed
+
Cross-platform install — macOS + Linux parity
+
All setup scripts MUST test on both macOS (bash 3.2) and Linux (bash 5.x). Bash 3.2 compatibility gates: no declare -A, no [[ regex with ERE, no EPOCHSECONDS. CI matrix MUST include both targets.
+
+ +
How to promote a proposed principle: (1) draft formal write-up with concrete enforcement rule + CI gate, (2) operator approves via lockin widget, (3) write to references/principles.md, (4) flip card class from .proposed to current.
+
+
+ + +
+
+

⑨ Failure Taxonomy (§9)

+

+ +
+
+

Axis 1 — Surface

+
    +
  • +
  • +
  • +
+
+
+

Axis 2 — Layer

+
    +
  • +
  • +
  • +
+
+
+

Axis 3 — Severity

+
    +
  • +
  • +
  • +
+
+
+
Fill from: SKILL.md §9 + references/workflows/rca.md. The 3-axis taxonomy is the source of truth for failure categorization. All report.html.tpl badges derive from this taxonomy.
+
+
+ +
+ + + +
+ + + + +
+
+

📊 Success Criteria Matrix

+

Fill the Evidence column as transcripts arrive. Update the pill class to flip status. Group rows by functional area.

+ +
Pill flow:p-white awaits-evidence → 🌑 p-yellow awaits-dogfood → 🔵 p-blue unit-tested → 🟢 p-green verified → 🔴 p-red failed
+ +

🚪 Area — Core Functionality

+ + + + + + + + + + + + + + + + + + + + + + + + +
FeatureVerification methodStatusEvidenceWhere
⚪ evidenceawaits transcript
🌑 dogfoodawaits dogfood run
+ +

🔍 Area — Agents

+ + + + + + + + + + + + + + + + + +
FeatureVerificationStatusEvidenceWhere
⚪ evidencerequires real-world trigger
+ +

🏭 Area — Configuration

+ + + + + + + + + + + + + + + + + +
FeatureVerificationStatusEvidenceWhere
⚪ evidenceawaits config test
+ +
How to update: when evidence arrives, (a) replace <em>awaits...</em> with actual evidence (transcript in <details>, PR link, screenshot ref), (b) swap pill class. Add a new <h4> + <table> per functional area.
+
+
+ + +
+
+

🌐 Skill Context Map

+

Mermaid diagram showing how agents, scripts, templates, and references connect at runtime.

+ + +
+%%{init: {'theme':'dark'}}%% +flowchart LR + CLI([CLI invocation]) --> SETUP[Setup §0\ndetect.ts] + SETUP -->|config ok| SLICER[slicer.ts\nslice findings] + SLICER --> TIER0[tier0-scan.ts\nquick surface scan] + TIER0 --> DISPATCH[run.sh\ndispatch analyzer] + DISPATCH --> ANALYZER[diagnostics-analyzer\nsub-agent] + ANALYZER --> RENDER[render.ts\nbuild report] + RENDER --> REPORT[report.html\ndelivered to user] + + DISPATCH --> APPLYWORKER[apply-worker\nsub-agent] + APPLYWORKER -->|PRs| GH[GitHub PRs] + + classDef script fill:#1c1c2a,stroke:#06b6d4,color:#f5f5f9; + classDef agent fill:#1c1c2a,stroke:#a78bfa,color:#f5f5f9; + classDef output fill:#1c1c2a,stroke:#10b981,color:#f5f5f9; + class SLICER,TIER0,RENDER script; + class ANALYZER,APPLYWORKER agent; + class REPORT,GH output; +
+ +
How to fill: Replace the placeholder flowchart above with the actual runtime context map for Wave-{{WAVE_N}}. Colour classes: script (cyan), agent (purple), output (green).
+
+
+ + +
+
+

⏳ Audit Timeline

+

Ordered record of significant design decisions, PR landings, and dogfood events for Wave-{{WAVE_N}}.

+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
Wave-{{WAVE_N}} kickoff
+
+
+
+
+
+ + +
+
+

📊 Design Principles Audit

+

Cross-reference each principle against Wave-{{WAVE_N}} changes. Mark pass / skip / fail per principle. Links to §8 in the Skill Overview tab for full principle text.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PrincipleTitleStatusEvidence / NotesWave touch
PR-001⚪ not-checkedwave changes don't touch this surface
PR-019No inline Python heredocs🟢 passfetch.sh: no python3 heredocs found (grep clean)scripts/cli/run.sh
PR-024 proposedPortability — no hard-coded paths🌑 pendingaudit not yet run for this wavescripts/**
PR-025 proposedRenderer smoke-test🌑 pendingsmoke test not yet writtenassets/templates/report.html.tpl
PR-026 proposedCross-platform install🌑 pendingLinux CI matrix not yet addedscripts/setup/*
+ +
Proposed principles (PR-024/025/026): These are hypothesis-stage. The audit row tracks whether this wave's changes are compatible with the proposed enforcement rule. A "pass" here strengthens the case for formal adoption; a "fail" needs a design discussion first.
+
+
+ +
+ + + +
+ +
+

📑 Document Map — informational dependencies (upstream / downstream)

+

When a doc changes, what else needs to follow? This Mermaid graph surfaces the dependency graph so we don't miss any propagation. Update the graph when the skill's reference tree changes.

+ +
+%%{init: {'theme':'dark'}}%% +flowchart LR + SKILL[SKILL.md] -->|"§0 ref"| DETECT[scripts/setup/detect.ts] + SKILL -->|"§4 BoM"| RUNSH[scripts/cli/run.sh] + SKILL -->|"§4 BoM"| ALL_SCRIPTS[scripts/*.ts] + SKILL -->|"§5 agents"| ANALYZER[assets/agents/diagnostics-analyzer.md] + SKILL -->|"§5 agents"| APPLYWORKER[assets/agents/diagnostics-apply-worker.md] + SKILL -->|"§6 refs"| REF[references/reference.md] + SKILL -->|"§6 refs"| PRINC[references/principles.md] + SKILL -->|"§6 refs"| WF_ONBOARD[references/workflows/onboarding.md] + SKILL -->|"§6 refs"| WF_DIAG[references/workflows/diagnostics.md] + SKILL -->|"§6 refs"| WF_ORCH[references/workflows/orchestrator-protocol.md] + SKILL -->|"§6 refs"| WF_APPLY[references/workflows/apply-dispatch.md] + SKILL -->|"§6 refs"| WF_RCA[references/workflows/rca.md] + SKILL -->|"§7 config"| CONFIG[references/config.md] + WF_ORCH -->|"loaded by"| SETUP[scripts/setup/*] + WF_DIAG -->|"drives"| SLICER[scripts/slicer.ts] + WF_DIAG -->|"drives"| TIER0[scripts/tier0-scan.ts] + WF_RCA -->|"drives"| RENDER[scripts/report/render.ts] + RENDER -->|"uses"| TPL[assets/templates/report.html.tpl] + WF_APPLY -->|"drives"| APPLYWORKER + WF_APPLY -->|"format"| APPLY_FMT[references/workflows/apply-pr-comment-format.md] + APPLY_FMT -->|"template"| PRBODY[assets/templates/pr-body.md.tpl] + CONFIG -->|"schema"| SCHEMA[scripts/config/schema.ts] + CONFIG -->|"template"| CFGTPL[assets/templates/config.yaml.tpl] + PRINC -.->|"enforces"| ALL_SCRIPTS + PRINC -.->|"enforces"| TPL + + classDef doc fill:#1c1c2a,stroke:#a78bfa,color:#f5f5f9; + classDef code fill:#1c1c2a,stroke:#06b6d4,color:#f5f5f9; + classDef tpl fill:#1c1c2a,stroke:#10b981,color:#f5f5f9; + class SKILL,REF,PRINC,WF_ONBOARD,WF_DIAG,WF_ORCH,WF_APPLY,WF_RCA,CONFIG,APPLY_FMT doc; + class DETECT,RUNSH,ALL_SCRIPTS,SETUP,SLICER,TIER0,RENDER,SCHEMA code; + class TPL,PRBODY,CFGTPL tpl; + class ANALYZER,APPLYWORKER doc; +
+ +
Legend: Purple nodes = documentation files (.md). Cyan nodes = code / scripts (.ts · .sh). Green nodes = runtime templates (.tpl). Dashed arrows = enforcement relationships (principles constrain code quality, not data flow). Solid arrows = data / configuration flow.
+
+ +
+

Change-propagation table — when X changes, also update Y

+

Before merging a PR that touches any file in the left column, verify ALL downstream items are also updated.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
If you change……also update (downstream)Why
SKILL.md §4 BoMscripts/cli/run.sh comment block + references/reference.md treeScript invocation convention must match the BoM spec. Reference tree must list all scripts.
references/workflows/diagnostics.mdscripts/slicer.ts + scripts/tier0-scan.ts inline commentsWorkflow document drives script behaviour. Script comments cite the workflow step.
references/workflows/rca.md taxonomySKILL.md §9 + scripts/report/render.ts + assets/templates/report.html.tpl badge classes3-axis taxonomy is the source of truth. Report badges + render logic derive from it.
references/principles.md (any PR-N)Wave audit matrix (Audit tab §8) + cross-cutting scripts in scope of that principlePrinciples enforce skill quality. Each wave's audit verifies compliance.
assets/templates/report.html.tplscripts/report/render.ts renderFindingPanel() call-sitesRenderer-template contract: render.ts constructs the data the template expects. They must stay in sync.
scripts/config/schema.tsreferences/config.md field table + assets/templates/config.yaml.tplSchema is the source of truth for config shape. Docs and template must reflect it.
assets/agents/*.md (agent spec)SKILL.md §5 agent roster + references/workflows/orchestrator-protocol.md Steps 6 & 11Agent registry in §5 must match actual agent files. Orchestrator protocol lists agent names explicitly.
references/workflows/apply-dispatch.mdassets/agents/diagnostics-apply-worker.md + references/workflows/apply-pr-comment-format.mdApply workflow drives the apply-worker agent and the PR comment format used in apply PRs.
references/workflows/onboarding.mdscripts/setup/detect.ts + SKILL.md §0Onboarding workflow is the spec for the setup detection script.
+ +
How to maintain: When a PR adds a new cross-file dependency (e.g. a new script that reads from a config key, or a new template field the renderer writes), add a row here BEFORE merging. This table is the propagation contract.
+
+ + +
+

Upstream inputs to this wave

+

Dependencies this wave relies on that must be stable (from prior waves, other PRs).

+ + + + + + + + + + + + + + + + +
ArtifactSourceStabilityNotes
🟢 stable
🌑 in-flight
+ +

Downstream consumers of this wave

+

What breaks or needs updating if this wave's artifacts change shape.

+ + + + + + + + + + +
ConsumerDepends onImpact if brokenNotes
+
+ +
+ + + +
+ + +
+ +
+ + + + + + + + + + + + + + + + diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md new file mode 100644 index 00000000..f9a3d3a1 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.1-nl-query.md @@ -0,0 +1,59 @@ +# WF-2.1 — Natural Language Query Entry + +> Entry point for a diagnostics run. +> User states what they want in plain language; skill translates to TraceFilter. + +## Trigger + +User says: "run diagnostics", "diagnose my agents", "why is my agent failing?", +"check last week's agent sessions", etc. + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ mutagent-diagnostics — Running │ +│ │ +│ What would you like to diagnose? │ +│ (or press Enter to use defaults from config.yaml) │ +│ │ +│ Examples: │ +│ • "Why did my search agent fail last week?" │ +│ • "Show me sessions with negative feedback" │ +│ • "Analyze errors from yesterday" │ +│ • "Check the checkout-agent sessions" │ +│ │ +│ > _ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## NL → TraceFilter Translation + +The orchestrator translates the query: + +| NL Fragment | TraceFilter Field | +|-------------|------------------| +| "last week" | `time_window.from = "7daysAgo"` | +| "yesterday" | `time_window.from = "1daysAgo"` | +| "errors" / "failed" | `has_error = true` | +| "negative feedback" | `has_feedback = true, score_below = ` | +| "search agent" | `agent_id = "search-agent"` | +| (empty / Enter) | use `config.yaml` defaults | + +## After Translation + +Show confirmation before running: + +``` + Interpreted as: + • Time window: last 7 days + • Filter: errors only + • Agent: all agents + • Limit: 100 traces + + [1] Run with these filters + [2] Adjust filters + [3] Cancel +``` + +→ On confirm: proceed to WF-2.2 (tier-0 scan progress) diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md new file mode 100644 index 00000000..900a2b4c --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.2-tier0-progress.md @@ -0,0 +1,58 @@ +# WF-2.2 — Tier-0 Scan Progress + +> Displayed while tier-0-scan.ts runs (CODE-FIRST pre-LLM analysis). +> This runs before any LLM call — fast, deterministic. + +## Display (In Progress) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Running diagnostics... │ +│ │ +│ [1/4] Fetching traces from langfuse... ████░░ 62% │ +│ [2/4] Tier-0 scan (pre-LLM)... ░░░░░░ 0% │ +│ [3/4] Deep analysis (LLM)... pending │ +│ [4/4] Rendering report... pending │ +│ │ +│ Fetched 73 trace metadata records │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Display (After Tier-0 Scan) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Running diagnostics... │ +│ │ +│ [1/4] Fetching traces... ████████ done │ +│ [2/4] Tier-0 scan (pre-LLM)... ████████ done │ +│ [3/4] Deep analysis (LLM)... ████░░░░ 55%│ +│ [4/4] Rendering report... pending │ +│ │ +│ Tier-0 findings: │ +│ • Error spike: 12 errors in last 2h (threshold: 3) │ +│ • Latency spike: p95 = 45s (threshold: 15s) │ +│ • Analyzing 4 trace clusters (cap: 5) │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Tier-0 Pattern Summary (shown after step 2) + +| Pattern | Found | Value | +|---------|-------|-------| +| P-001 Error spike | Yes | 12 errors / 2h (threshold: 3) | +| P-002 Latency spike | Yes | p95=45s (threshold: 15s) | +| P-003 Feedback cluster | No | — | + +## Slice Plan Display + +``` + Slice plan (cap=5): + Cluster 1: 8 error traces (2026-05-27 10:00–12:00) + Cluster 2: 5 high-latency traces + Cluster 3: 3 negative-feedback traces + Cluster 4: 2 remaining samples + → 4 clusters queued (under cap of 5) +``` + +→ Proceeds automatically to WF-2.3 (LLM analysis running) diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md new file mode 100644 index 00000000..71a88432 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.3-analysis-progress.md @@ -0,0 +1,44 @@ +# WF-2.3 — LLM Analysis Progress + +> Displayed while diagnostics-analyzer sub-agents run in parallel (cap: 5). +> Each cluster is analyzed by one sub-agent. + +## Display (Parallel Execution) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Deep analysis running (4 clusters, cap=5) │ +│ │ +│ Cluster 1 [errors, 8 traces] ████████ complete │ +│ Cluster 2 [latency, 5 traces] ████░░░░ tier-2... │ +│ Cluster 3 [feedback, 3 traces] ██░░░░░░ tier-1... │ +│ Cluster 4 [sample, 2 traces] ░░░░░░░░ queued │ +│ │ +│ Findings so far: 3 critical, 1 warning │ +│ Budget: 142s elapsed / 240s cap │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Analysis Tiers (shown in progress labels) + +| Label | Tier | +|-------|------| +| "tier-0..." | Pre-LLM pattern scan | +| "tier-1..." | Known pattern matching | +| "tier-2..." | Tree-based structural analysis | +| "tier-3..." | Deep structural (LLM) | +| "tier-4..." | LLM deviation detection | +| "complete" | All tiers done for this cluster | + +## Budget Exhaustion Warning + +If budget cap (240s) is reached before all clusters complete: +``` + ⚠ Analysis budget reached (240s). 1 cluster not fully analyzed. + Partial findings included in report. + + [1] View partial report + [2] Resume analysis (run again with narrower scope) +``` + +→ On all clusters complete: proceed to WF-2.4 (report HTML) diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md new file mode 100644 index 00000000..a1c01712 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.4-html-report.md @@ -0,0 +1,61 @@ +# WF-2.4 — HTML Report + Findings + +> Primary output of a diagnostics run. +> Rendered via `scripts/report/render.ts` using `assets/templates/report.html.tpl`. + +## Layout + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ mutagent-diagnostics — Report │ +│ Generated: 2026-05-27 10:42 | Source: langfuse | 73 traces │ +├─────────────────────────────────────────────────────────────────┤ +│ [3 CRITICAL] [1 WARNING] [0 OK] [73 traces] │ +├─────────────────────────────────────────────────────────────────┤ +│ Discovered Checks │ +│ ┌──────────────┬──────────┬──────────┬─────────┐ │ +│ │ Check │ Pattern │ Severity │ Found │ │ +│ ├──────────────┼──────────┼──────────┼─────────┤ │ +│ │ Error spike │ P-001 │ critical │ ✓ yes │ │ +│ │ Latency p95 │ P-002 │ critical │ ✓ yes │ │ +│ │ Low feedback │ P-003 │ warning │ ✓ yes │ │ +│ └──────────────┴──────────┴──────────┴─────────┘ │ +├─────────────────────────────────────────────────────────────────┤ +│ Findings │ +│ ▼ [CRITICAL] Tool call timeout causing search failures │ +│ WHAT: tool-timeout WHY: env-config WHERE: tool-invocation │ +│ Evidence: ▸ 8 traces, latency p95 = 45s │ +│ Root cause: SEARCH_TIMEOUT env var missing → default 5s │ +│ ───────────────────────────────────────────────────────── │ +│ REMEDY: Set SEARCH_TIMEOUT=30000 in .mutagentrc │ +│ Target: local-claude (config) │ +│ [ Copy markdown ] [ Accept fix ] │ +│ │ +│ ▶ [CRITICAL] Prompt hallucination on empty product list... │ +│ ▶ [WARNING] Feedback cluster: 3 sessions scored <2/5... │ +└─────────────────────────────────────────────────────────────────┘ +│ [ Copy as Markdown ] │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## Finding Card Layers (4 layers per PR-014) + +1. **Header**: severity badge + title + WHAT/WHY/WHERE taxonomy chips (collapsed by default) +2. **Evidence**: trace IDs, message excerpts, score values, timestamps +3. **RCA chain**: recursive why-chain until origin (no fixed depth) +4. **Remedy**: target platform, change type, copy button, Accept/Dismiss actions + +## HITL Interaction + +- **Copy markdown**: copies finding + remedy as markdown to clipboard +- **Accept fix**: triggers apply-worker for this specific finding (→ WF-3.1) +- **Dismiss**: marks finding as dismissed (recorded in audit) + +## Report File + +Report is written to: `.mutagent/diagnostics/reports/report-.html` +Path is printed to console: +``` + Report written to: .mutagent/diagnostics/reports/report-2026-05-27T10-42.html + Opening in browser... +``` diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md new file mode 100644 index 00000000..8d284b3a --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.5-rca-detail.md @@ -0,0 +1,69 @@ +# WF-2.5 — RCA Detail Expansion + +> Expanded view of root cause analysis for a single finding. +> Shown when user clicks "expand" on a finding card in WF-2.4. + +## Display (Expanded Finding Card) + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ ▼ [CRITICAL] Tool call timeout causing search failures │ +│ │ +│ WHAT: tool-timeout WHY: env-config WHERE: tool-invocation │ +│ │ +│ Evidence (8 traces) │ +│ ────────────────────────────────────────────────────────── │ +│ tr_abc123 2026-05-27 10:05 duration: 47.2s error: timeout │ +│ tr_abc124 2026-05-27 10:08 duration: 46.9s error: timeout │ +│ tr_abc125 2026-05-27 10:11 duration: 45.1s error: timeout │ +│ (+ 5 more) │ +│ │ +│ Root Cause Chain │ +│ ────────────────────────────────────────────────────────── │ +│ Why 1: Tool call `search` exceeded timeout limit │ +│ Evidence: "Error: ETIMEDOUT after 5000ms" │ +│ │ +│ Why 2: Default timeout is 5s; search API requires 15–30s │ +│ Evidence: search API docs, observed latency p50=18s │ +│ │ +│ Why 3: SEARCH_TIMEOUT env var not set in .mutagentrc │ +│ Evidence: env probe shows SEARCH_TIMEOUT undefined │ +│ │ +│ Origin: Missing env configuration (env-config class) │ +│ │ +│ Remedy │ +│ ────────────────────────────────────────────────────────── │ +│ Type: config-patch │ +│ Target: local-claude (local-agent class) │ +│ Action: Add SEARCH_TIMEOUT=30000 to .mutagentrc │ +│ │ +│ [ Copy markdown ] [ Accept fix ] [ Dismiss ] │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## RCA Chain Rules (from references/workflows/rca.md) + +- No fixed depth — recurse until the ORIGIN is reached (a WHY that has no further cause) +- Every WHY node must cite evidence from the trace (not inference) +- Origin must map to one of the 8 WHERE categories + +## Finding JSON Shape (shown on demand via "Copy JSON") + +```json +{ + "id": "f-001", + "severity": "critical", + "what": "tool-timeout", + "why": "env-config", + "where": "tool-invocation", + "summary": "Tool call timeout causing search failures", + "evidence": [...], + "whyChain": [ + { "depth": 1, "reason": "...", "evidence": "..." }, + { "depth": 2, "reason": "...", "evidence": "..." }, + { "depth": 3, "reason": "...", "evidence": "..." } + ], + "origin": { "depth": 3, "reason": "...", "evidence": "..." }, + "remedy": { ... } +} +``` diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md new file mode 100644 index 00000000..2b052656 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/diagnostics/WF-2.6-stale-warning.md @@ -0,0 +1,53 @@ +# WF-2.6 — Stale Diagnosis Warning + +> Shown when the user tries to apply a fix, but the codebase has changed since diagnosis. +> `scripts/stale-detector.ts` detects this by comparing git hashes. + +## Trigger + +User clicks "Accept fix" on a finding card in WF-2.4, but `stale-detector.ts` returns `stale=true`. + +## Display + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ ⚠ Stale Diagnosis │ +│ │ +│ The codebase has changed since this diagnosis was run. │ +│ │ +│ Diagnosed at: abc1234f (2026-05-27 09:00) │ +│ Current HEAD: f4e2a991 (2026-05-27 10:42) │ +│ Changed files: 3 │ +│ │ +│ Applying fixes from a stale diagnosis may be incorrect. │ +│ │ +│ [1] Re-run diagnostics on current HEAD (recommended) │ +│ [2] Apply anyway (I know what I'm doing) │ +│ [3] Cancel │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## On "Re-run" (Recommended) + +→ Restart diagnostics from WF-2.1 with the same filters as the original run +→ Previous report is archived to `.mutagent/diagnostics/reports/archived/` + +## On "Apply Anyway" + +→ Proceed to WF-3.1 with a `stale=true` flag in the audit record +→ Audit.json will record `staleCheck.status = "stale-override"` +→ PR title will include "(stale diagnosis)" suffix for visibility + +## Hash Comparison Logic + +```typescript +// scripts/stale-detector.ts +const diagnosedHash = audit.diagnosedAtHash; // hash at diagnosis time +const currentHash = getCurrentGitHash(); // HEAD at apply time + +if (diagnosedHash !== currentHash) { + const changedFiles = getChangedFiles(diagnosedHash, currentHash); + return { stale: true, diagnosedHash, currentHash, changedFiles }; +} +return { stale: false }; +``` diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md new file mode 100644 index 00000000..350163a0 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.1-welcome.md @@ -0,0 +1,60 @@ +# WF-1.1 — Welcome / Entry Point + +> Phase 1 of onboarding: detect setup state and route user. +> Rendered as: numbered chat options (chat-multi-choice) or AskUserQuestion (Claude Code) + +## Trigger + +User runs: `pnpx @mutagent/diagnostics init` + +## Setup State Detection + +`scripts/setup/detect.ts` runs first: + +``` +SetupState = "missing" | "partial" | "complete" +``` + +## Route Matrix + +| State | Route | +|-------|-------| +| `missing` | → WF-1.2 (source platform picker) | +| `partial` | → WF-1.7 (resume partial setup) | +| `complete` | → WF-1.8 (run diagnostics now?) | + +## Display (State = "missing") + +``` +┌─────────────────────────────────────────────────────────────┐ +│ mutagent-diagnostics — Setup │ +│ │ +│ Welcome! Let's configure diagnostics for your AI agents. │ +│ │ +│ This will take about 5 minutes. │ +│ │ +│ [1] Get started → (detect source platform) │ +│ [2] Show what will be configured │ +│ [3] Exit │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Display (State = "partial") + +``` +┌─────────────────────────────────────────────────────────────┐ +│ mutagent-diagnostics — Resume Setup │ +│ │ +│ Partial config found. Missing fields: │ +│ • target.platform │ +│ • ask_tool.runtime │ +│ │ +│ [1] Resume setup │ +│ [2] Start over (backup existing config) │ +│ [3] Exit │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Display (State = "complete") + +→ Skip to WF-1.8 diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md new file mode 100644 index 00000000..e695d95c --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.2-source-platform-picker.md @@ -0,0 +1,41 @@ +# WF-1.2 — Source Platform Picker + +> Phase 2 of onboarding: pick the trace source platform. +> Prev: WF-1.1 | Next: WF-1.3 + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 1 of 7 — Where are your agent traces stored? │ +│ │ +│ [1] Langfuse (cloud or self-hosted) │ +│ [2] OpenTelemetry / Jaeger (OTel-compatible backend) │ +│ [3] Local JSONL file (.jsonl or .ndjson) │ +│ [4] Claude Code sessions (auto-detected) │ +│ [5] Codex CLI sessions (auto-detected) │ +│ [6] I don't know yet (skip, configure later) │ +└─────────────────────────────────────────────────────────────┘ +``` + +## On Selection + +| Choice | Action | +|--------|--------| +| 1 (Langfuse) | → WF-1.3a (Langfuse auth check) | +| 2 (OTel) | → WF-1.3b (OTel endpoint check) | +| 3 (Local JSONL) | → WF-1.3c (file path input) | +| 4 (Claude Code) | → probe `~/.claude/projects/` → WF-1.4 | +| 5 (Codex) | → probe `~/.codex/sessions/` → WF-1.4 | +| 6 (Skip) | → Set `source.platform: null` → WF-1.4 | + +## Validation + +After selection, validate connectivity: +- Langfuse: `langfuse traces list --limit 1` → check exit code +- OTel: `curl -m 5 $ENDPOINT/health` → check response +- Local JSONL: `ls $FILE` → check file exists +- Claude Code: `ls ~/.claude/projects/` → count sessions +- Codex: `ls ~/.codex/sessions/` → count sessions + +If validation fails → show inline error + offer retry or skip diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md new file mode 100644 index 00000000..3815561a --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.3-source-auth.md @@ -0,0 +1,75 @@ +# WF-1.3 — Source Auth / Connection + +> Phase 3 of onboarding: configure source connectivity. +> Prev: WF-1.2 | Next: WF-1.4 + +## WF-1.3a — Langfuse Auth + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 2 of 7 — Langfuse Connection │ +│ │ +│ Checking .mutagentrc for LANGFUSE_* keys... │ +│ │ +│ ✓ LANGFUSE_SECRET_KEY found │ +│ ✓ LANGFUSE_PUBLIC_KEY found │ +│ ✓ LANGFUSE_HOST found (https://cloud.langfuse.com) │ +│ │ +│ Testing connection... ✓ Connected (12 traces found) │ +│ │ +│ [1] Continue with this config │ +│ [2] Use a different host │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Keys Not Found Path + +``` + ✗ LANGFUSE_SECRET_KEY not found in .mutagentrc + + Add the following to your .mutagentrc file: + + LANGFUSE_SECRET_KEY=sk-... + LANGFUSE_PUBLIC_KEY=pk-... + LANGFUSE_HOST=https://cloud.langfuse.com + + [1] I've added the keys — retry + [2] Skip Langfuse, choose another source +``` + +## WF-1.3b — OTel Endpoint + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 2 of 7 — OTel Endpoint │ +│ │ +│ OTel endpoint (from .mutagentrc or enter): │ +│ > http://localhost:4318 │ +│ │ +│ Testing connection... ✓ Jaeger reachable │ +│ │ +│ [1] Continue │ +│ [2] Change endpoint │ +└─────────────────────────────────────────────────────────────┘ +``` + +## WF-1.3c — Local JSONL File + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 2 of 7 — JSONL File Path │ +│ │ +│ Path to your trace file (.jsonl or .ndjson): │ +│ > traces.jsonl │ +│ │ +│ ✓ File found (247 lines) │ +│ │ +│ [1] Continue │ +│ [2] Enter a different path │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Key Rules + +- NEVER prompt for key values — only prompt for key NAMES to check in .mutagentrc +- Keys are referenced by name in config.yaml — never stored as values diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md new file mode 100644 index 00000000..454b20ee --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.4-target-picker.md @@ -0,0 +1,48 @@ +# WF-1.4 — Target Platform Picker + +> Phase 4 of onboarding: pick the apply target. +> Prev: WF-1.3 | Next: WF-1.5 + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 3 of 7 — Where should fixes be applied? │ +│ │ +│ Target class: │ +│ │ +│ LOCAL AGENTS (config changes only, HITL review) │ +│ [1] Claude Code (skills + settings) │ +│ [2] Codex CLI (config.toml) │ +│ [3] Cursor (.cursorrules + settings) │ +│ [4] OpenCode (opencode.json) │ +│ │ +│ LOCAL CODE CONSTRUCTS (code edits via PR, lint gate) │ +│ [5] Mastra.ai (TypeScript agents) │ +│ [6] Cloud Agent SDK (Anthropic / OpenAI / Google / etc.) │ +│ │ +│ REMOTE (REST API mutations, HITL always required) │ +│ [7] Cloud REST (Langfuse annotations, remote config) │ +│ │ +│ [8] Skip for now │ +└─────────────────────────────────────────────────────────────┘ +``` + +## On Selection + +| Choice | Target Platform | Target Class | +|--------|-----------------|--------------| +| 1 | local-claude | local-agent | +| 2 | local-codex | local-agent | +| 3 | local-cursor | local-agent | +| 4 | local-opencode | local-agent | +| 5 | local-mastra | local-code-construct | +| 6 | local-cloud-agent-sdk | local-code-construct | +| 7 | cloud-rest | remote | +| 8 | null | null | + +## Target Class Explanation (shown inline) + +- **local-agent**: reads config, proposes changes, you apply them (safe) +- **local-code-construct**: opens a PR branch, lint+typecheck gate before any merge +- **remote**: read-before-write, idempotent mutations, HITL confirmation for every change diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md new file mode 100644 index 00000000..1b2a7bf9 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.5-ask-tool.md @@ -0,0 +1,43 @@ +# WF-1.5 — ASK Tool Selection + +> Phase 5 of onboarding: configure the HITL interaction mode. +> Prev: WF-1.4 | Next: WF-1.6 + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 4 of 7 — How should I ask you questions? │ +│ │ +│ When diagnostics finds an issue and wants your input, │ +│ how do you want to respond? │ +│ │ +│ [1] Claude Code (AskUserQuestion) │ +│ Best if you're running this from Claude Code │ +│ │ +│ [2] Chat multi-choice │ +│ Numbered options in the conversation │ +│ Works everywhere: terminal, CLI, any chat │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Auto-Detection + +Before showing this screen, check if running in Claude Code: +- `process.env.CLAUDE_CODE_ENTRYPOINT` set → suggest [1] (Claude Code) +- Otherwise → suggest [2] (chat-multi-choice) + +## On Selection + +| Choice | `ask_tool.runtime` | +|--------|--------------------| +| 1 | `claude-code` | +| 2 | `chat-multi-choice` | + +## Context Note + +The ASK tool selection affects: +- Destructive-action gates: `AskUserQuestion` in Claude Code vs numbered prompt in chat +- HTML report copy-back: auto-paste to conversation (Claude Code) vs manual copy prompt (chat) +- No functional difference for read-only diagnostics — only matters at apply time diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md new file mode 100644 index 00000000..758b6b66 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.6-config-review.md @@ -0,0 +1,57 @@ +# WF-1.6 — Config Review + Write + +> Phase 6 of onboarding: review generated config and confirm write. +> Prev: WF-1.5 | Next: WF-1.7 (or WF-1.8 on first run) + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 5 of 7 — Review Configuration │ +│ │ +│ Here's what will be written to config.yaml: │ +│ │ +│ source: │ +│ platform: "langfuse" │ +│ config: {} │ +│ │ +│ target: │ +│ platform: "local-claude" │ +│ config: {} │ +│ │ +│ filters: │ +│ time_window: │ +│ from: "7daysAgo" │ +│ to: "now" │ +│ limit: 100 │ +│ │ +│ ask_tool: │ +│ runtime: "claude-code" │ +│ │ +│ schedule: │ +│ mode: "on-demand" │ +│ │ +│ self_diagnostics: │ +│ enabled: false │ +│ │ +│ [1] Write config and continue │ +│ [2] Go back to change a setting │ +│ [3] Exit without saving │ +└─────────────────────────────────────────────────────────────┘ +``` + +## On Confirm + +1. Write `config.yaml` from template (using `assets/templates/config.yaml.tpl`) +2. Run `scripts/config/validate.ts` on written file +3. If validation fails → show error + offer fix +4. If validation passes → advance to WF-1.7 + +## Validation Display + +``` + Writing config.yaml... ✓ + Validating... ✓ Config is valid + + [1] Continue to next step +``` diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md new file mode 100644 index 00000000..99a4039b --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.7-filter-defaults.md @@ -0,0 +1,52 @@ +# WF-1.7 — Filter Defaults + Scope + +> Phase 7 of onboarding: set default filter scope for diagnostics runs. +> Prev: WF-1.6 | Next: WF-1.8 + +## Display + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 6 of 7 — Default Scope │ +│ │ +│ How many traces should diagnostics analyze per run? │ +│ │ +│ [1] Last 7 days, up to 100 traces (recommended) │ +│ [2] Last 24 hours, up to 50 traces (fast) │ +│ [3] Last 30 days, up to 500 traces (thorough) │ +│ [4] Custom │ +│ │ +│ Errors-only mode: │ +│ [Y] Include errors only (faster, higher signal) │ +│ [N] Include all traces (default) │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Custom Path + +``` + Custom filter configuration: + + Time window from ("7daysAgo", "24h", ISO date): > 7daysAgo + Time window to ("now", ISO date): > now + Max traces: > 100 + Filter to errors only? (y/n): > n + Filter by agent ID (leave empty for all): > +``` + +## On Confirm + +Updates `filters` section in `config.yaml`: +```yaml +filters: + time_window: + from: "7daysAgo" + to: "now" + has_error: null # null = all + limit: 100 +``` + +## Note on Score Filters + +Score-based filters are NOT set here — they require score-scale auto-discovery at runtime (iter-8). Thresholds are never hardcoded in config. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md new file mode 100644 index 00000000..5b0fa88f --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/assets/wireframes/onboarding/WF-1.8-first-run.md @@ -0,0 +1,59 @@ +# WF-1.8 — First Run Prompt + +> Phase 8 of onboarding: offer to run diagnostics immediately after setup. +> Prev: WF-1.7 (or WF-1.1 if setup already complete) + +## Display (After Fresh Setup) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Step 7 of 7 — Setup Complete │ +│ │ +│ ✓ config.yaml written │ +│ ✓ Connection validated │ +│ ✓ .mutagent/diagnostics/ initialized │ +│ │ +│ Run diagnostics now? │ +│ │ +│ [1] Yes, run diagnostics now │ +│ [2] No, I'll run it manually later │ +│ │ +│ To run manually: say "run diagnostics" or "diagnose my │ +│ agents" in your AI coding session, or: │ +│ pnpx @mutagent/diagnostics run │ +└─────────────────────────────────────────────────────────────┘ +``` + +## Display (Already Set Up) + +``` +┌─────────────────────────────────────────────────────────────┐ +│ mutagent-diagnostics — Ready │ +│ │ +│ Config: ✓ valid │ +│ Source: langfuse (connected) │ +│ Target: local-claude │ +│ │ +│ [1] Run diagnostics now │ +│ [2] Reconfigure │ +│ [3] Exit │ +└─────────────────────────────────────────────────────────────┘ +``` + +## On "Run Now" + +→ Trigger diagnostics orchestrator (equivalent to `pnpx @mutagent/diagnostics run`) +→ Jump to WF-2.1 (diagnostics entry point) + +## On "Run Later" + +``` + To run diagnostics: + + • In your AI coding session: say "run diagnostics on my agents" + • From CLI: pnpx @mutagent/diagnostics run + + Config saved at: ./config.yaml + + Done! +``` diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-findings.json b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-findings.json new file mode 100644 index 00000000..7f660182 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-findings.json @@ -0,0 +1,92 @@ +{ + "sessionId": "sample-session-001", + "diagnosedAt": "2026-05-28T12:00:00.000Z", + "sourcePlatform": "local-jsonl", + "targetPlatform": "local-claude", + "totalTraces": 12, + "findings": [ + { + "findingId": "F-001", + "actionable": "Tool call to 'search' returns empty results 60% of the time — agent retries in a loop without a fallback", + "assumptions": [ + "Tool timeout is the primary cause of empty results (hypothesis-pending-source: search.ts timeout config not yet read)", + "No existing retry-cap exists in the tool definition" + ], + "failureOrigin": { + "what": "loop", + "why": "tool-missing", + "where": "tool-definition", + "evidence": "session-abc123 → message[14]: tool_result empty string, repeated 4×", + "confidence": "high" + }, + "whyChain": [ + { + "why": "Agent repeatedly calls search tool", + "evidence": "Trace messages 10-18: tool_use 'search' 4× in 90s", + "isOrigin": false + }, + { + "why": "Search tool returns empty body on API timeout", + "evidence": "Tool result content: '' on 4/6 calls in session-abc123", + "isOrigin": false + }, + { + "why": "No fallback path defined when search returns empty — agent loops", + "evidence": "tool-definition: search.ts missing timeout guard + empty-result branch", + "isOrigin": true + } + ], + "remedies": [ + { + "remedyId": "R-001-a", + "title": "Add empty-result guard + max-retry cap to search tool definition", + "applyTarget": "scripts/tools/search.ts", + "failureOrigin": { + "what": "loop", + "why": "tool-missing", + "where": "tool-definition", + "evidence": "tool-definition: search.ts:42", + "confidence": "high" + }, + "diff": { + "before": "if (!result) { return searchTool(query); }", + "after": "if (!result || retries >= MAX_RETRIES) { return { found: false, fallback: true }; }" + }, + "cost": "low", + "correctness": "high", + "rank": 1, + "targetClass": "local-code-construct" + }, + { + "remedyId": "R-001-b", + "title": "Add system-prompt instruction: 'If search returns empty after 2 attempts, summarize what you know and halt'", + "failureOrigin": { + "what": "loop", + "why": "prompt-underspec", + "where": "system-prompt", + "evidence": "system-prompt: no loop-break instruction present", + "confidence": "medium" + }, + "cost": "low", + "correctness": "medium", + "rank": 2, + "targetClass": "local-agent" + } + ], + "sourceTraceIds": ["session-abc123"], + "referenceIds": { + "traceId": "session-abc123", + "sessionId": "session-abc123", + "findingId": "F-001" + } + } + ], + "discoveredChecks": [ + { + "checkId": "DC-001", + "name": "Retry-loop detector", + "description": "Detects consecutive identical tool calls without intervening reasoning", + "affectedTraceIds": ["session-abc123"] + } + ] +} diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-meta.json b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-meta.json new file mode 100644 index 00000000..9241e39d --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/examples/sample-meta.json @@ -0,0 +1,47 @@ +[ + { + "traceId": "trace-meta-001", + "sessionId": "session-meta-001", + "hasError": false, + "hasFeedback": true, + "rawScore": 1.5, + "latencyMs": 3200, + "sourcePlatform": "local-jsonl", + "skillBehaviorDeviationCount": 2, + "agentId": "diagnostics-orchestrator", + "startTime": "2026-05-28T10:00:00.000Z", + "endTime": "2026-05-28T10:00:03.200Z", + "totalTokens": 8420, + "tags": ["self-diagnostics", "phase-3-c"] + }, + { + "traceId": "trace-meta-002", + "sessionId": "session-meta-001", + "hasError": false, + "hasFeedback": false, + "rawScore": 4, + "latencyMs": 1100, + "sourcePlatform": "local-jsonl", + "skillBehaviorDeviationCount": 0, + "agentId": "diagnostics-analyzer", + "startTime": "2026-05-28T10:00:03.500Z", + "endTime": "2026-05-28T10:00:04.600Z", + "totalTokens": 3210, + "tags": ["self-diagnostics"] + }, + { + "traceId": "trace-meta-003", + "sessionId": "session-meta-002", + "hasError": true, + "hasFeedback": false, + "sourcePlatform": "local-jsonl", + "skillBehaviorDeviationCount": 1, + "agentId": "diagnostics-orchestrator", + "startTime": "2026-05-28T11:00:00.000Z", + "endTime": "2026-05-28T11:00:02.100Z", + "totalTokens": 5640, + "apiErrors": [ + { "retryAttempt": 1, "maxRetries": 3, "timestamp": "2026-05-28T11:00:01.000Z" } + ] + } +] diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/adapter-strategy.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/adapter-strategy.md new file mode 100644 index 00000000..52b0cd4c --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/adapter-strategy.md @@ -0,0 +1,75 @@ +# Adapter Strategy — Q1-Q6 Locked Decisions + +> All Q1-Q6 → Option A. Locked iter-5. See decisions-log.md for operator verbatim answers. + +## Q1 — Per-platform reference docs + +**Decision**: Per-platform reference doc + ONE normalization script per source. + +Each source platform has: +- `references/source-platforms/.md` — CLI operation manual + filter examples + credential setup + hyperlinks +- `scripts/normalize/platforms/.ts` — Platform JSON → canonical TraceBody shape + +Custom platforms: drop a new reference doc + normalize.ts. The orchestrator discovers it from config.yaml `source.platform`. + +## Q2 — Normalization in script + +**Decision**: Normalization is deterministic mapping in a TypeScript script. + +The normalize scripts are Type A (pure, no LLM, no I/O). They receive raw platform JSON and emit canonical `TraceBody`. This makes normalization testable, reproducible, and cost-free. + +The agent NEVER interprets raw platform JSON directly — it always reads via the normalized shape. + +## Q3 — CLI install detection at onboarding + +**Decision**: CLI install detection at onboarding via `Bash(which )` + AskUserQuestion install prompt if missing. + +Trigger: operator picks a source/target platform during onboarding. Agent immediately checks: +```bash +Bash("which langfuse") # or equivalent +``` +If missing, prompt with the install command from the per-platform reference doc. +Do NOT proceed with that platform until CLI is confirmed present. + +## Q4 — Target apply: the shared `mutagent-cli apply` transport (SUPERSEDED — M9/DC-5) + +**Original decision**: target applies were pure agent operations run by the bespoke +`diagnostics-apply-worker` (Bash git/gh + Bash curl). + +**Superseded (M9/DC-5)**: the apply-worker is RETIRED. Its three branches (local worktree-PR · +remote REST · vendor) are now the shared `mutagent-cli apply` target adapters +(`@mutagent/tools` src/apply — one `TargetAdapter` contract: read → dryRun → apply → rollback → +emitAudit). At the Step-11 gate, ai-engineer (the WRITE actor) produces the amended artifact and +shells `mutagent-cli apply --kind --target --dry-run` → `--commit`. Apply is +non-destructive (REST create-rev+activate; git-revert never force-push) + always audited. The +skill layer gates BEFORE the CLI (DC-1); the CLI holds no approval logic. + +## Q5 — Idempotency via uuidgen + +**Decision**: `Bash(uuidgen)` generates the idempotency key for REST writes. + +Every remote PUT includes `Idempotency-Key: {uuid}`. Same key on retry → server ignores duplicate. Retry on 5xx (max 2 attempts). Escalate to operator on persistent failure. + +## Q6 — Custom platform extensibility + +**Decision**: Custom platform onboarding = drop new reference doc + normalize.ts. + +No plugin registry or config DSL. To add a new source platform: +1. Add `references/source-platforms/.md` with CLI operation manual + hyperlinks +2. Add `scripts/normalize/platforms/.ts` implementing `normalizeFile(content: string): TraceBody` +3. Update `scripts/config/schema.ts` to include the new platform literal + +The orchestrator reads `source.platform` from config and looks up the reference doc by convention. + +--- + +## Filter vs Search distinction + +| Term | What it is | Maps to | +|------|-----------|---------| +| **Filter** | Narrowing on trace metadata (agent ID, time, score, error flag, tags) | Native CLI `--flag` arguments | +| **Search** | Additional categorization on top of filter (full-text, semantic, by content match) | Additional API call OR client-side post-filter | + +Master Filter/Search Coverage Matrix: `filter-search-matrix.md` + +For unknown platforms: agent does runtime CLI docs lookup — `Bash( --help)` + WebFetch upstream docs — and reasons over the help text to map dimensions. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config-migration.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config-migration.md new file mode 100644 index 00000000..a7eb8606 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config-migration.md @@ -0,0 +1,93 @@ +# Config Migration — v0.1.0 → v0.3.0 (Diagnostics) + +> **Skill-local mirror** of the framework migration directive (canonical copy: +> `mutagent-orchestrator/references/config-migration.md`). Load this when +> `scripts/config/load.ts` returns `migrationRequired: true` (a legacy shape was +> detected) or when `scripts/setup/detect.ts` reports `migrationRequired`. + +## Why a migration is needed + +The unified `.mutagent/config.yaml` changed shape in **v0.2.0**. The old per-skill +`diagnostics:` section named its own `source` / `target` / `schedule` / +`trigger_rules` / `heartbeat`. In v0.2.0 those move to shared, framework-owned +places so the whole ADL lifecycle shares one catalog. **Fork B — HARD-CUT:** the +loader NEVER parses the old shape at runtime. It detects a legacy config and emits +`migration-required`; you rewrite the config in place (this directive), then re-run. + +There is **no static migration script for v0.1.0** — that one is a directive an +agent applies under the `*onboard` gate. + +A **v0.2.0** config is different: its delta to v0.3.0 is just steps 8–9 below (two +mechanical, lossless transforms), so helix AUTO-MIGRATES it in place on load +(`migrateConfigObject` / `migrateConfigFile` in +`mutagent-orchestrator/scripts/config-schema.ts` — comments preserved, no `.bak`, +since `config.yaml` is git-tracked). You only apply steps 8–9 by hand when doing a +v0.1.0 migration, so that it lands on **0.3.0** rather than the superseded 0.2.0. + +## Legacy detection (what trips `migration-required`) + +Any ONE of these fires (see `detectLegacyShape` in `scripts/config/load.ts`): + +- `config_version` is absent or not a recognised version (the frozen literal is `"0.3.0"`; + `"0.2.0"` is accepted and auto-migrated by helix — see step 9). +- A legacy top-level key is present: `shared` · `stages` · a top-level + `diagnostics` · a top-level `evaluator`. + +## The rewrite (apply in place) + +| # | v0.1.0 (old) | v0.3.0 (new) | +|---|---|---| +| 1 | `shared:` | **`global:`** (rename) | +| 2 | `diagnostics.source: { platform, endpoint, credential_ref, paths, format, agent_field, latency_unit }` | **`global.sources: [ { name, platform, project?, endpoint?, credential_ref?, paths?, format?, agent_field?, latency_unit? } ]`** — give it a `name`; bound BY ROLE (source-consumer), no `source_ref`. | +| 3 | `diagnostics.target: { platform, mode, root, rest_base_url, credential_ref }` | **`global.targets: [ { name, platform, mode, root?, rest_base_url?, repo_url?, code_refs?, credential_ref?, apply: { kind } } ]`** — give it a `name` + an `apply.kind`; bound BY ROLE (target-writer). A `platform: report-only` target becomes `apply.kind: report-only` (or set `lifecycle.diagnostics.apply: report-only` and omit the target). | +| 4 | top-level `diagnostics:` section | **`lifecycle.diagnostics:`** (nest under `lifecycle`) | +| 5 | `diagnostics.schedule` · `diagnostics.trigger_rules` · `diagnostics.heartbeat` | **`triggers.diagnose: { enabled, rules, schedule?, heartbeat? }`** (top-level `triggers`, ships disabled) | +| 6 | `credential_ref: SOME_ENV` | unchanged, but WIDENED — may now be `credential_ref: { env: SOME_ENV, path: ../secrets/.env }` | +| 7 | any `*.observability` block | **REMOVED** — source binds by role via `global.sources` | +| 8 | `target.subject: code` | **`artifact_format: code`** — v0.3.0 dropped `code` from the `subject` enum (#1206); `artifact_format` is now the SOLE home of the `code` substrate. A code target is `subject: agent\|skill` × `artifact_format: code`. | +| 9 | `config_version: "0.1.0"` (or absent) | **`config_version: "0.3.0"`** (frozen literal) | + +Fields the diagnostics section KEEPS (now under `lifecycle.diagnostics`): +`apply` (new — the report-only gate), `context[]` (new — stage context links), +`ask_tool`, `default_audience`, `run_tags`, `self_diagnostics`, `feedback_sources`, +`agents[]`. + +## Before → after (minimal example) + +**Before (v0.1.0):** +```yaml +config_version: "0.1.0" +shared: + models: { default: sonnet, pinned_judge: sonnet } +diagnostics: + source: { platform: langfuse, credential_ref: LANGFUSE_SECRET_KEY } + target: { platform: report-only, mode: local } + ask_tool: { runtime: claude-code } + schedule: { mode: on-demand } + heartbeat: { max_diagnostics_per_day: 3 } +``` + +**After (v0.3.0):** +```yaml +config_version: "0.3.0" +global: + models: { default: sonnet, judge_model: sonnet } # pinned_judge → judge_model + sources: + - name: primary + platform: langfuse + credential_ref: LANGFUSE_SECRET_KEY +lifecycle: + diagnostics: + apply: report-only # was target.platform=report-only + ask_tool: { runtime: claude-code } +triggers: + diagnose: + enabled: false + rules: [] + schedule: { mode: on-demand } + heartbeat: { max_diagnostics_per_day: 3 } +``` + +After rewriting, re-run `scripts/setup/detect.ts ` — it should now +report `state: complete` (or a normal `partial` for genuinely-missing fields, NOT +`migrationRequired`). diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config.md new file mode 100644 index 00000000..8ec97f92 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/config.md @@ -0,0 +1,159 @@ +# Config Reference — config.yaml Schema with Doc Strings + +> Config location: `/.mutagent/config.yaml` +> Secrets location: `/.mutagentrc` (gitignored — never commit) +> Schema source of truth: `scripts/config/schema.ts` (TypeBox) + +## Full annotated config.yaml + +```yaml +# ──── SOURCE ───────────────────────────────────────────────────────────────── +# Where agent traces come from. +source: + # Source platform identifier. Required. + # Supported in v0.1: langfuse | otel | local-jsonl | claude-code | codex + platform: langfuse + + # Endpoint URL for the source platform. + # Empty = use default CLI auth / env vars. + # Set for self-hosted platforms (e.g., self-hosted Langfuse). + endpoint: "" + + # Key name in .mutagentrc for the source API secret. + # NEVER store the value here — only the key name. + # Example: LANGFUSE_SECRET_KEY → .mutagentrc has LANGFUSE_SECRET_KEY=sk-... + credential_ref: LANGFUSE_SECRET_KEY + +# ──── TARGET ───────────────────────────────────────────────────────────────── +# Where agent definitions live (apply remedies back here). +target: + # Target platform identifier. Required. + # local-agent: .claude/agents/*.md, .codex/agents/*.md, etc. + # local-code-construct: Mastra Agent, Cloud Agent SDK, LangGraph, etc. + # cloud-rest: REST API with GET/PUT for agent definition CRUD + platform: local-claude + + # Apply mode. Required. + # local = markdown file edits via BG worktree + PR + # remote = REST PUT with idempotency-key + mode: local + + # Root directory for local targets (relative to project root). + # Default: .claude/agents/ + root: .claude/agents/ + + # REST base URL for remote targets. + # rest_base_url: https://api.example.com/v1 + + # Key name in .mutagentrc for REST auth token. + # credential_ref: REST_API_TOKEN + +# ──── ASK TOOL ─────────────────────────────────────────────────────────────── +# Platform-native ASK mechanism. Auto-detected by cli/init.ts at first run. +# Override here if auto-detection is wrong. +ask_tool: + # Host coding-agent runtime. Required. + # claude-code | codex | cursor | opencode | generic + runtime: claude-code + + # Platform tool name for structured multi-select. + # AskUserQuestion on Claude Code; varies on other runtimes. + native_tool: AskUserQuestion + + # Fallback when native tool is unavailable. + # chat-multi-choice: numbered list in chat message + fallback: chat-multi-choice + +# ──── SCHEDULE ─────────────────────────────────────────────────────────────── +# When the orchestrator wakes to check trigger rules. +# v0.1 ships on-demand ONLY. Schedule structure prepared for post-v0.1 wiring. +# See references/workflows/schedule-prep.md for adding scheduling post-v0.1. +schedule: + # on-demand = operator manually invokes (v0.1 supported) + # daily-batch = native /loop or cron wake (post-v0.1) + mode: on-demand + + # For daily-batch: local time (HH:MM format) + at: "09:00" + + # Timezone. Defaults to system timezone. + # timezone: "America/New_York" + +# ──── TRIGGER RULES ────────────────────────────────────────────────────────── +# Which traces qualify for a diagnostic run when schedule fires or operator invokes. +# Each rule's match is a TraceFilter; traces matching ANY rule are diagnosed. +trigger_rules: + - name: high-latency-errors + match: + latency_p99_ms_above: 5000 + has_error: true + action: diagnose + + - name: feedback-bearing + match: + has_feedback: true + # score_below is computed via score-scale auto-discovery (iter-8) + # Do NOT hardcode here — let the orchestrator probe and compute threshold + action: diagnose + + # Example: specific agent filter + # - name: search-agent-failures + # match: + # agent_id: search-agent + # has_error: true + # action: diagnose + +# ──── HEARTBEAT ────────────────────────────────────────────────────────────── +# Controls notifications for scheduled (non-interactive) runs. +heartbeat: + # Whether to log when no triggers fire (no operator ping) + notify_on_zero_matches: false + + # Whether to notify operator when triggers fire and report is ready + notify_on_matches: true + + # Cost guardrail: max full diagnostic runs per day + max_diagnostics_per_day: 3 + +# ──── SELF DIAGNOSTICS [INTERNAL] ──────────────────────────────────────────── +# Skill diagnoses itself after usage session (PR-022). +# OFF by default for end users. ON for skill maintainers + dogfood mode. +self_diagnostics: + # Enable/disable self-diagnostics. Default: false. + enabled: false + + # Cadence: per-session | daily | manual + cadence: per-session + + # Source: auto-detect host (claude-code | codex) + source: host-coding-agent + + # Branch for self-remedy PRs (use {date} placeholder) + remedy_branch: mutagent/self-diagnostics/{date} + + # [INTERNAL] prefix added to all self-remedy PR titles + marker: "[INTERNAL]" +``` + +## TraceFilter fields (for trigger_rules.match) + +| Field | Type | Description | +|-------|------|-------------| +| `agent_id` | string | Filter by agent identifier | +| `session_id` | string | Filter by specific session/trace ID | +| `start_time` | ISO8601 string | Start of time window | +| `end_time` | ISO8601 string | End of time window | +| `has_error` | boolean | Only traces with error events | +| `has_feedback` | boolean | Only traces with attached feedback | +| `score_below` | number | Traces with score below threshold (computed by orchestrator from scale probe) | +| `latency_p99_ms_above` | number | Traces with P99 latency above threshold (ms) | +| `by_skill` | string | Traces where a specific skill was triggered | +| `by_route` | string | Traces with a specific operation name | +| `by_tag` | string[] | Traces with specific tags | + +## Security notes + +- `config.yaml` is committed to the project repository (non-secrets only) +- `.mutagentrc` is gitignored and holds actual secret values +- The `credential_ref` field in config.yaml is a KEY NAME pointing to `.mutagentrc`, never the value +- Three-layer protection: `.gitignore` pattern + `git check-ignore` before any write + PR-time `git status` check diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/filter-search-matrix.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/filter-search-matrix.md new file mode 100644 index 00000000..9137bbe6 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/filter-search-matrix.md @@ -0,0 +1,66 @@ +# Filter/Search Coverage Matrix + +> Master Matrix — per-platform support for each filter/search dimension. +> Ships with the skill. Updated by PRs when platform support changes. +> For unknown platforms: runtime CLI docs lookup (see adapter-strategy.md Q6). + +## Dimension definitions + +| Dimension | What it filters/searches | +|-----------|-------------------------| +| by agent ID | Traces from a specific agent identifier | +| by session ID | A specific session/trace ID | +| by time window | Traces in a time range | +| by score | Traces with score above/below threshold | +| has feedback | Traces with any attached feedback | +| has error | Traces containing error events | +| latency P99 | Traces with high latency | +| by route / trace name | Traces with a specific operation name | +| by tag | Traces with specific labels/tags | +| by skill | Traces where a specific skill was triggered | +| Search: full-text | Content-level search in trace messages | +| Search: semantic | Semantic similarity search | + +--- + +## Coverage Matrix + +| Dimension | Langfuse | OTel | local-jsonl | claude-code | codex | +|-----------|----------|------|-------------|-------------|-------| +| by agent ID | `--agent-id` CLI flag | `span.attr[gen_ai.agent.id]` | post-filter on `agentId` field | filename pattern or content grep | grep `agent_type` field in rollout JSONL | +| by session ID | `--session-id` CLI flag | `trace_id` | post-filter on `sessionId` field | filename = session-id | filename = session-id in `~/.codex/sessions/` | +| by time window | `--from` / `--to` CLI flags | span `startTime` / `endTime` | post-filter on `startTime` timestamp | file `mtime` (`find -newer`, `-newer`) | file `mtime` in `~/.codex/sessions/` | +| by score | `--score-below` / `--score-above` flags | partial — depends on emitter | if `score` field present | limited — only `/feedback` thumbs (discrete boolean) | limited — check rollout for custom score field | +| has feedback | `--has-feedback` flag | partial — depends on emitter | if `hasFeedback` field present | limited — check for `/feedback` approval events | via `approval` events in rollout JSONL | +| has error | `--has-error` flag | `span.status.code == 2 (ERROR)` | post-filter on `hasError` field | grep `isError: true` in tool_result events | grep `error` events in rollout JSONL | +| latency P99 | native aggregation | compute from span `duration` | compute from `startTime`/`endTime` | derive from event timestamps | derive from event timestamps in rollout | +| by route / trace name | `--name` flag | span `name` field | partial — if `route` field present | n/a (single-route per session) | n/a (single-thread) | +| by tag | `--tag` flag | `span.attr[tags]` | partial — if `tags` field present | n/a | n/a | +| by skill | via tag/metadata (`--tag skill:`) | via `span.attr[skill]` | grep `skill` metadata field | grep `Skill` tool calls in JSONL | grep skill invocations in rollout events | +| Search: full-text | partial — via SDK filter, not CLI | no — post-fetch grep required | grep over jsonl lines | grep over session jsonl lines | grep over rollout jsonl lines | +| Search: semantic | no | no | no | no | no | + +--- + +## Lookup strategy + +### Known platforms (Langfuse, OTel, local-jsonl, claude-code, codex) + +Use the Master Matrix above. Reference doc for each platform has concrete CLI examples. + +### Unknown / custom platforms + +Agent does **runtime CLI docs lookup**: +1. `Bash(" --help")` — read help text +2. `WebFetch(upstream-docs-url)` — fetch from the URL in `references/source-platforms/.md` +3. Reason over help text → map dimensions to CLI flags + +If mapping is ambiguous, surface to operator via AskUserQuestion. + +--- + +## Notes + +- **Semantic search**: not supported on any platform in v0.1. Post-v0.1 consideration. +- **Codex score support**: Codex doesn't ship a feedback primitive natively. Check `codex-rs/rollout/src/lib.rs` for custom score fields if the operator's Codex build includes them. +- **Claude Code score**: limited to `/feedback` approval (thumbs-up/down boolean). Scale type = `boolean`. Negative = `false`/`"down"`. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/harness-knowledge.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/harness-knowledge.md new file mode 100644 index 00000000..bdef3621 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/harness-knowledge.md @@ -0,0 +1,22 @@ +# Platform Knowledge Table + +> Expandable table. Static info ships with the skill. +> Runtime details (latest CLI flags, current API endpoints) recovered via the linked upstream docs. +> Add new harnesses by submitting a PR to this file. + +| Harness | Transcript path (static) | ASK primitive | Schedule primitive | Upstream docs | +|---------|--------------------------|---------------|-------------------|---------------| +| **Claude Code** | `~/.claude/projects//.jsonl` (plaintext JSONL; 30-day default retention via `cleanupPeriodDays`) | `AskUserQuestion` tool — structured multi-select, `preview` attr for code/diff comparisons. Native. | Native `/loop` + `CronCreate` + `ScheduleWakeup` tools. | [code.claude.com/docs](https://code.claude.com/docs/en/) | +| **Codex CLI** | `~/.codex/sessions/.jsonl` (active) + `~/.codex/archived_sessions/.jsonl` (archived). Config: `~/.codex/config.toml`. Constants `SESSIONS_SUBDIR="sessions"` + `ARCHIVED_SESSIONS_SUBDIR="archived_sessions"` in `codex-rs/rollout/src/lib.rs`. Default-on; suppress with `codex exec --ephemeral`. | Approval prompts via TUI (Windows toast fallback). No structured-picker tool primitive yet — chat-based multi-choice. | External cron + `codex exec` for non-interactive runs. No native scheduler. | [developers.openai.com/codex](https://developers.openai.com/codex/cli) · [codex-rs/rollout source](https://github.com/openai/codex/tree/main/codex-rs/rollout) | +| **Cursor** | Local SQLite under VSCode-style workspace storage (e.g. `~/Library/Application Support/Cursor/User/workspaceStorage//state.vscdb` on macOS). Verify at runtime via probe. | Chat-based confirmation. No public structured-picker tool surfaced. | Background Agents (2025+) — autonomous task primitive; verify scheduling support at runtime. | [cursor.com/docs](https://cursor.com/docs) | +| **OpenCode** | Path TBD — runtime probe at onboarding. | Chat-based (Plan mode + general prompting). | None documented — use OS cron. | [opencode.ai/docs](https://opencode.ai/docs) | +| *Add more harnesses here* | *operator adds rows over time* | | | | + +--- + +## Notes + +- **Encoding of Claude Code project paths**: Claude Code encodes the absolute project path into the directory name under `~/.claude/projects/`. The encoding is an internal detail — `cli/init.ts` probes by trying known encodings and falls back to listing all project dirs. +- **Codex paths confirmed iter-8**: path confirmed from `codex-rs/rollout/src/lib.rs` source constants. If paths change in a future Codex release, update this table and the Codex adapter in `@mutagent/tools` (`mutagent-cli trace fetch --platform codex` — the skill no longer owns a Codex normalizer post-UniTF-flip). +- **Semantic search**: not supported on any harness in v0.1. +- **Schedule recovery**: platform scheduling specifics (exact API, cron syntax, daemon setup) are recovered at runtime by the agent via the upstream docs links above. This table stores only static facts. diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/memory-format.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/memory-format.md new file mode 100644 index 00000000..ee52fcd8 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/memory-format.md @@ -0,0 +1,78 @@ +# AutoMemory Format — project-level operator-feedback + tool-lessons + +> **Standard (mirrored across ADL skills — parity).** The subject of AutoMemory is +> the **TOOL + operator preferences**, NOT the diagnosed agent (that is the +> gitignored class-memory library). ONE project-level store for the whole lifecycle. +> Fixed convention + standardized format; NOT a config field. +> +> Read/write helpers: `scripts/memory/read.ts` + `scripts/memory/append.ts`. + +## Location + shape + +``` +.mutagent/memory/ ← project-level, COMMITTED + MEMORY.md ← index: `- [Title](.md) — ` one line/entry + .md ← one FACT per file +``` + +Each `.md` entry — Claude-Code AutoMemory format (verbatim): + +```markdown +--- +name: +description: +metadata: + type: user | feedback | project | reference # Claude Code's four types + lifecycle: spec|build|evaluate|diagnose|optimize|general # ADL extension + created: YYYY-MM-DD # REQUIRED · every memory is DATED (stale-pruning) +--- + + +``` + +- **Every entry DATED** (`metadata.created`). The date is an ABSOLUTE `YYYY-MM-DD` + (injected `now` for determinism in `appendMemory`). +- `MEMORY.md` is an **index only** — one `- [Title](.md) — ` line per + entry, sorted by slug. The `` is the entry's `description`. +- **Dedupe on append**: an existing slug is UPDATED in place and its `created` date + REFRESHED (never a duplicate file). + +## Feedback → type CLASSIFICATION rubric (verbose) + +Decision order — **first match wins**: + +| # | Feedback about… | → type | Signals | Body | +|---|---|---|---|---| +| 1 | external resource | `reference` | URL · dashboard · ticket · dataset path | pointer + what it's for | +| 2 | who the operator is | `user` | "I'm the lead" · standing preference | the trait | +| 3 | how the tool should behave | `feedback` | "stop surfacing X" · "too verbose" · "next time…" | fact + **Why:** + **How to apply:** | +| 4 | ongoing work/goals/constraints | `project` | "migrating to…" · "don't touch Z until…" | fact + **Why:** + **How to apply:** | + +**Do NOT save:** +- Anything already in code / config / git (it is already the source of truth). +- Ephemeral facts relevant to only ONE run. +- Subject FINDINGS about the diagnosed agent (those go to the class-memory library + `.mutagent/diagnostics/library/`, gated by operator approval — NOT here). + +## Lifecycle filter at recall + +At run START (parse-brief / Step 3a) the diagnostics run loads memory FILTERED to +`lifecycle ∈ { diagnose, general }` (`readDiagnoseMemory`) — the diagnostics stage's +own lessons plus the always-relevant `general` facts. Entries tagged for other +stages (`spec` / `build` / `evaluate` / `optimize`) are skipped for a diagnose run. + +## When to append (write trigger) + +At run FINALIZE (finalize-gate / Step 9.9), when the operator gives feedback ABOUT +the tool or a standing preference, classify it with the rubric above and call +`appendMemory({ slug, name, description, type, lifecycle, body, now })`. The default +`lifecycle` for diagnostics-run feedback is `diagnose` (use `general` for a +tool-wide standing preference). + +## Memory subsystems (NOT competing — different subjects) + +| Subsystem | Subject | Content | Write trigger | Location | +|---|---|---|---|---| +| **Class-memory library** | diagnosed entity | journal + regex patterns + deep-read ledger | operator-APPROVED findings only | `.mutagent/diagnostics/library/…` · gitignored | +| **feedback_sources** | diagnosed entity | external signals → enrich findings | read-only, per-run | opt-in config | +| **AutoMemory** (this doc) | the tool + operator | usage-feedback + lessons (Claude format, dated, classified) | operator feedback | `.mutagent/memory/` · committed | diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/onboarding-decisions.yaml b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/onboarding-decisions.yaml new file mode 100644 index 00000000..3bd198c3 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/onboarding-decisions.yaml @@ -0,0 +1,187 @@ +# references/onboarding-decisions.yaml +# R-SELF-07-a: Structured option lists for each onboarding decision phase. +# Used by the parent session (inline orchestrator) when presenting choices to the operator. +# +# Each decision has: +# id — machine ID for the choice +# label — human-readable label shown to operator +# value — written to config.yaml when chosen +# platform_doc — (optional) references/source-platforms/{value}.md path to load +# note — (optional) rendered below the option if selected +# +# R-SELF-07-b: Every option list MUST end with the Custom escape hatch entry +# { label: 'Custom — describe what you have', value: '__custom__' } +# so the operator is never blocked on an unsupported platform. + +version: "1.0" + +decisions: + + # Phase 1 — Source platform + source_platform: + question: "Where do your agent traces live?" + key: source_platform + options: + - id: langfuse + label: "Langfuse (cloud or self-hosted)" + value: langfuse + platform_doc: "references/source-platforms/langfuse.md" + - id: otel + label: "OpenTelemetry-compliant endpoint" + value: otel + platform_doc: "references/source-platforms/otel.md" + - id: local-jsonl + label: "Local trace file (.jsonl / .ndjson)" + value: local-jsonl + platform_doc: "references/source-platforms/local-jsonl.md" + - id: claude-code + label: "Claude Code local transcripts (~/.claude/projects/…/*.jsonl)" + value: claude-code + platform_doc: "references/source-platforms/claude-code.md" + - id: codex + label: "Codex local transcripts (~/.codex/sessions/*.jsonl)" + value: codex + platform_doc: "references/source-platforms/codex.md" + - id: __custom__ + label: "Custom — describe what you have" + value: __custom__ + note: "Describe your trace format. Orchestrator will attempt a general-purpose fallback and guide credential setup." + + # Phase 4 — Target platform (where agent definitions live) + target_platform: + question: "Where do your agent definitions live?" + key: target_platform + options: + - id: local-claude + label: "Claude Code agents (.claude/agents/*.md)" + value: local-claude + platform_doc: "references/target-platforms/local-claude.md" + - id: local-codex + label: "Codex agents (.codex/agents/*.md)" + value: local-codex + platform_doc: "references/target-platforms/local-codex.md" + - id: local-cursor + label: "Cursor agents (cursor-equivalent dir)" + value: local-cursor + platform_doc: "references/target-platforms/local-cursor.md" + - id: local-opencode + label: "OpenCode agents (opencode-equivalent dir)" + value: local-opencode + platform_doc: "references/target-platforms/local-opencode.md" + - id: mastra + label: "Mastra code construct (source code: new Agent({...}))" + value: mastra + platform_doc: "references/target-platforms/mastra.md" + - id: anthropic-cloud + label: "Anthropic Cloud Agent SDK (source code)" + value: anthropic-cloud + platform_doc: "references/target-platforms/anthropic-cloud.md" + - id: rest-api + label: "Cloud REST API (HTTP GET/PUT)" + value: rest-api + platform_doc: "references/target-platforms/rest-api.md" + - id: __custom__ + label: "Custom — describe where your agents live" + value: __custom__ + note: "Describe your agent storage format. Orchestrator will attempt the general-purpose code-construct apply path." + + # Phase 5b agent install scope + agent_install_scope: + question: "Install diagnostics-* agents: project-scope or user-global?" + key: agent_install_scope + options: + - id: project + label: "Project-scope (recommended — visible in repo's .claude/agents/)" + value: project + note: "Writes to $PROJECT_ROOT/.claude/agents/ — committed, visible to all contributors." + - id: user + label: "User-global (~/.claude/agents/ — available in all projects)" + value: user + note: "Writes to ~/.claude/agents/ — not in repo, convenient for personal setups." + - id: __custom__ + label: "Custom path — specify manually" + value: __custom__ + note: "You will be prompted for the exact destination directory." + + # Phase 5c dry-spawn verification offer + agent_dry_spawn: + question: "Agents verified. Want to dry-spawn each with a no-op probe?" + key: agent_dry_spawn + options: + - id: yes + label: "Yes — probe all 3 (safe: no trace data read, no writes)" + value: yes + note: "Dispatches each agent with prompt: 'echo: probe' and confirms they activate." + - id: no + label: "No — skip, I trust the verification" + value: no + - id: __custom__ + label: "Custom — probe only specific agents" + value: __custom__ + note: "Specify which agents to probe by name." + + # Phase 6 — Trigger rules + # ⏸ DISABLED for v0.1: do NOT ask this question. v0.1 is always on-demand. + # Auto-write `schedule.mode: on-demand` without prompting. Re-enable (flip + # disabled: false) when scheduling lands post-v0.1. Config field is KEPT. + trigger_mode: + disabled: true + default: on-demand + question: "When should diagnostics run?" + key: schedule.mode + options: + - id: on-demand + label: "On-demand (I invoke it manually) — recommended for v0.1" + value: on-demand + - id: scheduled + label: "I'll set up scheduling later (structure prepared)" + value: on-demand + note: "Config will contain schedule.mode: on-demand. Edit references/workflows/schedule-prep.md to wire scheduling post-v0.1." + - id: __custom__ + label: "Custom — describe your trigger" + value: __custom__ + note: "Orchestrator will translate your description into a trigger rule. May require schedule.mode: scheduled." + + # Phase 6 — Trigger condition + trigger_condition: + question: "Add a trigger condition? (optional)" + key: trigger_condition + options: + - id: score-threshold + label: "Diagnose when score < threshold (threshold auto-discovered)" + value: score-threshold + - id: error-rate + label: "Diagnose when error rate > 20%" + value: error-rate + - id: none + label: "No trigger condition — manual invocation only" + value: none + - id: __custom__ + label: "Custom filter — describe in natural language" + value: __custom__ + note: "Orchestrator will translate your description into a TraceFilter." + + # Phase 8 — First-run pick + first_run: + question: "Setup complete! What would you like to diagnose first?" + key: first_run + options: + - id: last-24h + label: "Diagnose traces from the last 24 hours" + value: last-24h + - id: most-recent-failing + label: "Diagnose your most recently failing agent" + value: most-recent-failing + - id: negative-feedback-week + label: "Diagnose all sessions with negative feedback this week" + value: negative-feedback-week + - id: high-latency + label: "Diagnose all high-latency sessions" + value: high-latency + - id: manual + label: "I'll invoke manually later" + value: manual + - id: __custom__ + label: "Custom — describe what you want to diagnose" + value: __custom__ + note: "Orchestrator will translate your description into a TraceFilter." diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/operation-inventory.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/operation-inventory.md new file mode 100644 index 00000000..c9bf9b37 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/operation-inventory.md @@ -0,0 +1,59 @@ +# Operation Inventory — Type A/B/C Classification + +> Per PR-019. Every operation is exactly one type. No overlap. +> Used as the audit surface for code review of new contributions. + +## Classification Rules + +- **Type A — Pure Script**: deterministic logic, structured I/O. Written in TypeScript, invoked via `Bash("scripts/cli/run.sh scripts/.ts ...")`. Zero LLM calls. Testable in isolation. +- **Type B — Agent Operation**: uses agent's native tools (Bash for external CLI, Agent for sub-dispatch, AskUserQuestion/equivalent for HITL, Read/Edit/Write for files). LLM reasoning. Cannot be unit tested in isolation. +- **Type C — Hybrid**: agent invokes a Type A script, passes structured input, reads structured output. Script provides deterministic shape; agent decides when/how to invoke it. + +--- + +## Type A — Pure Scripts (9 scripts, 2 self-diagnostics) + +| Op | File | Why script | +|----|------|-----------| +| Tier 0 static scan | `scripts/tier0-scan.ts` | Deterministic pattern matching + signal counts | +| Trace slicing | `scripts/slicer.ts` | Deterministic math + cap-of-5 clustering | +| Config load | `scripts/config/load.ts` | YAML parse + env lookup | +| Config schema | `scripts/config/schema.ts` | TypeBox type definitions | +| Config validation | `scripts/config/validate.ts` | Schema validation + typed errors | +| Trace normalization | `scripts/normalize/platforms/*.ts` | Platform JSON → canonical shape | +| Setup detection | `scripts/setup/detect.ts` | File reads + state checks | +| Stale-target hash compare | `scripts/stale-detector.ts` | Pure hash compare | +| HTML report render | `scripts/report/render.ts` | Template + data → HTML | +| [INTERNAL] Host probe | `scripts/self-diagnostics/probe.ts` | Env + fs probing | +| [INTERNAL] Self-dispatch | `scripts/self-diagnostics/dispatch.ts` | Descriptor file write | + +--- + +## Type B — Agent Operations (12 items) + +| Op | Agent action | +|----|-------------| +| Sub-agent dispatch | `Agent({subagent_type: 'diagnostics-analyzer', run_in_background: true})` | +| Trace fetch from source | `Bash( traces list ...)` per per-platform reference doc | +| Score-scale probe | `Bash( scores list --json)` + LLM classification | +| NL → TraceFilter translation | LLM reasoning over operator query | +| Cross-analyzer dedup | LLM reasoning over collected findings | +| RCA (3-dim WHAT/WHY/WHERE) | LLM reasoning per finding | +| Recursive whys | LLM reasoning (PR-020) | +| Remedy ranking | LLM judgment (cost × correctness) | +| HITL approval gate | `AskUserQuestion` / chat-fallback | +| BG-worktree apply | `Bash(git worktree + commit + push + gh pr create)` | +| REST apply | `Bash(curl GET + PUT)` with idempotency-key | +| CLI install check | `Bash(which )` + prompt (PR-021) | + +--- + +## Type C — Hybrid (orchestrator invoking scripts) + +| Op | Pattern | +|----|---------| +| Orchestrator invoking tier0 | Agent calls `Bash(scripts/cli/run.sh scripts/tier0-scan.ts ...)` → reads structured JSON output | +| Orchestrator invoking slicer | Agent calls `Bash(scripts/cli/run.sh scripts/slicer.ts ...)` → reads slice plan JSON | +| Apply-worker invoking stale-detector | Agent calls `Bash(scripts/cli/run.sh scripts/stale-detector.ts ...)` → reads freshness result | +| Orchestrator invoking report render | Agent calls `Bash(scripts/cli/run.sh scripts/report/render.ts ...)` → reads report.html path | +| Init invoking setup/detect | Agent calls `Bash(scripts/cli/run.sh scripts/setup/detect.ts)` → routes based on SetupState | diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/overview.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/overview.md new file mode 100644 index 00000000..a13c74de --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/overview.md @@ -0,0 +1,167 @@ +# mutagent-diagnostics — Overview + +> **PRD-SO-01** · First reading for new users. This is the primer; `SKILL.md` is the +> manifest. Load `references/reference.md` next for the full architecture + dependency graph. + +--- + +## What this skill does + +`mutagent-diagnostics` is a diagnostics-on-tap skill for AI agents. Given access to your +agent traces (from Langfuse, OpenTelemetry, local JSONL, Claude Code transcripts, or Codex +transcripts), the skill runs a full RCA cycle and produces a gold-standard HTML report +covering every detected failure with ranked remedies, a two-rationale remedy card, a feedback +block grounded in operator chat and trace scores, and a copy-back markdown bundle you can +hand straight to an apply agent. + +The skill operates as an inline orchestrator running inside your coding-agent session. It +dispatches up to five parallel Analyzer sub-agents, aggregates their structured findings, +enriches them deterministically, and renders the result. No external server, no subscription, +no separate process — the skill IS the orchestrator. + +On first invocation the skill detects whether a config exists. If not, it walks you through +an eight-phase onboarding: source platform, target platform, ASK tool, schedule mode, and +trigger rules. Subsequent invocations go straight to the diagnostic pipeline. + +--- + +## When to use it + +| Trigger | Example | Outcome | +|---------|---------|---------| +| A user reported an agent failure | "my sample-email-agent returned wrong data" | Full RCA with WHAT/WHY/WHERE taxonomy, ranked remedies | +| Trace score dropped | Langfuse score fell below 0.6 | Cost-scoped analysis; coverage-proofed findings | +| You shipped a change and want a pre-release check | Before merging a prompt update | Structured findings vs declared success criteria (contract mode) | +| You suspect methodology drift in your diagnostics skill | Skill maintainer running self-diag | `[INTERNAL]` META-audience report; `--self-diag` flag | +| You want a neutral survey of the last 24h | No specific complaint | Window-based slicer; exploratory open-ended report | + +**When NOT to use it:** +- Real-time alerting — the skill produces a point-in-time report, not a streaming monitor. +- Replacing your observability platform — the skill reads FROM your platform, not instead of it. +- Scheduling automated runs — v0.1 is on-demand only; see `references/workflows/schedule-prep.md`. + +--- + +## Quick-start (5-minute onboarding) + +### Step 1 — Install (one-time) + +```bash +pnpx @mutagent/diagnostics init +``` + +This detects your runtime, copies required templates, and launches the onboarding wizard. + +### Step 2 — Run the wizard + +The onboarding wizard asks four questions: + +1. **Source platform** — where your traces live (Langfuse / OTel / local JSONL / Claude Code / Codex). +2. **Target platform** — where your agent definitions live (e.g., `.claude/agents/` for Claude Code agents; `cloud-rest` for remote agents; `report-only` to skip apply entirely). +3. **ASK tool** — auto-detected from your runtime. +4. **Trigger rules** — which traces qualify for diagnosis (e.g., `score_below: 0.6`). + +Config is saved to `/.mutagent/config.yaml`. Secrets (API keys) live in +`/.mutagentrc` (gitignored). + +### Step 3 — Diagnose + +In your coding-agent chat: + +``` +/mutagent-diagnostics +``` + +Or with a brief: + +``` +/mutagent-diagnostics "diagnose sample-email-agent focus on cost loops last 24h" +``` + +The brief is parsed into `{ agent, timeWindow, focus, residual }` by +`scripts/invocation/parse-brief.ts`. A `focus` directive activates Guided mode (the Guided +tab replaces Overview). No focus means a neutral survey. + +### Step 4 — Review the report + +The skill opens an HTML report in your browser. The report has four tab types: + +- **Methodology [INTERNAL]** — how the diagnosis was run (orchestrator trace, decisions log). +- **Overview** — entity card, 6-tile big-stat row, 24h latency heatmap, findings table. +- **F-NNN tabs** — one per finding: severity badge, taxonomy chips, problem, evidence, + why-chain, assumptions, coverage proof, ranked remedies. +- **Decisions** — live-preview markdown bundle; check remedies, add notes, click Copy. + +### Step 5 — Apply + +Paste the copied markdown bundle into your coding-agent chat. The apply worker spawns a +background agent on an isolated worktree, makes the changes, and opens a PR. + +--- + +## Anatomy of a diagnostic report + +For the full panel-by-panel anatomy — every block in the issue card, every element in the +remedy card, the live-preview mechanics — see: + +``` +references/workflows/rendering-anatomy.md +``` + +Key elements per finding panel: + +| Block | Location | Notes | +|-------|----------|-------| +| Severity badge | Top-left | CRIT / HIGH / MED / INFO | +| Taxonomy chips | Below title | WHAT · WHY · WHERE · APPLY · AUDIENCE | +| Feedback block | Between Problem and Evidence | Color-coded by source (chat=cyan, score=yellow, external=purple). Only appears when `feedbackSources[]` is populated. | +| Why-chain | Below evidence | Causal steps; deepest marked `isOrigin: true` | +| Assumptions | Below why-chain | Verified / unverified / hypothesis-pending pills | +| Coverage proof | Below assumptions | 4-dim widget (latency, score, temporal, tool-trajectory); low confidence shows yellow banner | +| Remedy card | Per remedy | Two-rationale blocks (purple Why + cyan WhyWorks); diff grid; apply plan + instructions; notes textarea | + +--- + +## What the skill does NOT do + +- **Does not monitor continuously.** It runs on-demand or on a schedule you configure. +- **Does not auto-apply without approval.** Every apply goes through a HITL copy-back gate. +- **Does not hallucinate entity data.** The entity card is populated deterministically from + trace metadata and your config — no LLM is involved in entity extraction. +- **Does not reveal PII.** The system prompt field in the entity card is always collapsed + (explicit click to view) regardless of size. +- **Does not run self-diagnostics automatically.** `self_diagnostics.enabled` defaults to + false; enabling it is a skill-maintainer opt-in. +- **Does not cross-reference other skills.** Each skill is a sealed unit. + +--- + +## Glossary + +| Term | Definition | +|------|------------| +| **Tier-0** | Static pattern scan (`scripts/tier0-scan.ts`) — runs BEFORE any LLM call to bound token cost. Measures cheap signals (latency distribution, error counts, score thresholds). | +| **RCA** | Root Cause Analysis — the 3-dimensional `(WHAT, WHY, WHERE)` failure taxonomy produced by the Analyzer agents. See `references/workflows/rca.md`. | +| **EntityContext** | Auto-extracted agent descriptor: name, model, system prompt, tool inventory with per-tool stats, input sample. Populated deterministically by the source-platform normalizer — no LLM. | +| **applyTarget** | The symbolic reference to the agent definition the remedy should be applied to (e.g., `.claude/agents/search-agent.md` for a local Claude agent). Declared by the Analyzer; rendered in the remedy meta strip. | +| **rationale** | The comparative remedy rationale block — WHY this remedy over alternatives (purple). Always visible, never collapsible. | +| **whyWorks** | The causal mechanism block — HOW the fix closes the failure (cyan). Always visible, never collapsible. | +| **coverageProof** | 4-dimensional sampling audit: for each of latency, score, temporal, and tool-trajectory, what fraction of the population buckets did the sample cover? Confidence mapped to high/med/low via 90/70 thresholds. | +| **Wave-6 methodology** | The diagnostic methodology layer (R2.1–R2.6 + D1/D2): mandatory LLM deep-read gate, awareness mini-sample, representative 4-bucket sampler, class-memory library, blind-spots taxonomy, and coverage proof. | +| **report-only** | A `target.platform` value that skips the apply gate entirely. Useful for read-only environments or when you want a report without committing to any changes. | +| **feedbackSources** | Structured list of operator feedback linked to a finding: chat messages (`chat`), Langfuse trace scores (`trace-score`), or external feedback platform entries (`external`). | + +--- + +## Further reading (progressive disclosure) + +| Doc | When to read | +|-----|-------------| +| `references/reference.md` | Full architecture DAG + complete TOC | +| `references/workflows/orchestrator-protocol.md` | The step-by-step diagnostic run procedure | +| `references/workflows/onboarding.md` | Onboarding phase-by-phase detail | +| `references/workflows/rca.md` | RCA taxonomy + finding shape | +| `references/workflows/rendering-anatomy.md` | Canonical per-finding + per-remedy anatomy | +| `references/principles.md` | 53 design principles (PR-001..PR-053) — the audit surface | +| `references/config.md` | Full config schema with doc strings and examples | +| `SKILL.md` | The manifest: §0 setup detection, §3 architecture, §4 bill of materials | diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/reference.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/reference.md new file mode 100644 index 00000000..1549bc74 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/reference.md @@ -0,0 +1,124 @@ +# mutagent-diagnostics — Reference Entry Point + +> Load this first. It provides the full architecture diagram, dependency graph, and TOC for all reference docs. + +## Architecture DAG + +> The Orchestrator is **NOT a sub-agent** — it is the parent coding-agent session following +> `references/workflows/orchestrator-protocol.md` inline (PR-024; the retired +> `diagnostics-orchestrator.md` is archived). The sub-agents are the analyzer (RCA) + the +> vendored apply actors (ai-engineer WRITE · ai-architect VERIFY) that drive the shared +> `mutagent-cli apply` — the bespoke apply-worker is retired (M9). + +```mermaid +flowchart TD + USER[Operator in coding agent] -->|invoke| SKILL[mutagent-diagnostics SKILL.md] + SKILL -->|§0 setup detect| DETECT{config present?} + DETECT -->|NO| ONB[Onboarding — references/workflows/onboarding.md] + DETECT -->|YES| ORCH[Orchestrator — parent session\nreferences/workflows/orchestrator-protocol.md] + ONB --> CFG[config.yaml + .mutagentrc] + CFG --> SKILL + ORCH -->|Bash CLI / file read| SRC[Source Platform — references/source-platforms/] + ORCH -->|bun tier0-scan.ts| TIER0[Tier 0 SCRIPT — scripts/tier0-scan.ts] + ORCH -->|normalize + extract EntityContext| NORM[Normalizers — scripts/normalize/platforms/*.ts\n+ entity-context.ts R1.7] + TIER0 -->|bun slicer.ts| SLICE[Slicer SCRIPT — scripts/slicer.ts] + ORCH -->|Agent dispatch| ANL[N Analyzers ≤5 — assets/agents/diagnostics-analyzer.md] + ANL --> ORCH + ORCH -->|LLM RCA reasoning| TL[RCA Layer — references/workflows/rca.md] + TL -->|Step 8.5: bun build-render-input.ts| ENRICH[Enricher — scripts/enrich/build-render-input.ts\ndeterministic · fail-loud] + NORM -->|EntityContext| ENRICH + ENRICH -->|bun render.ts| REPORT[report.html — assets/templates/report.html.tpl\ngold-standard multi-tab] + REPORT --> COPY{Operator pastes copy-back markdown} + COPY -->|approved, gated| APPLY[Shared apply — the BORROWED ai-engineer (canonical: mutagent-builder) then mutagent-cli apply @mutagent/tools] + APPLY -->|worktree-PR| LOCAL[Local Target — references/target-platforms/] + APPLY -->|REST create-rev| REMOTE[Remote Target — references/target-platforms/cloud-rest.md] +``` + +> **Borrowed actors.** `ai-engineer` (WRITE) and `ai-architect` (VERIFY) are owned by +> **mutagent-builder** and `discovery` by **mutagent-orchestrator**. This skill ships them in its +> standalone tarball, generated at `prepack` from the canonical (`mutagent-builder/.claude/skills/mutagent-builder/assets/agents/`), but does NOT track a +> copy — one agent, one committed source. See `scripts/release/vendored-agents.mjs`. + +## Dependency Graph + +```mermaid +flowchart LR + SKILL[SKILL.md] --> RF[reference.md] + SKILL --> RW0[workflows/orchestrator-protocol.md\nStep 8.5 = build render input] + SKILL --> RW1[workflows/onboarding.md] + SKILL --> RW2[workflows/diagnostics.md] + SKILL --> RW4[workflows/rca.md] + SKILL --> RP[principles.md] + SKILL --> RFL[operator-feedback-log.md] + SKILL --> ROP[operation-inventory.md] + SKILL --> RAS[adapter-strategy.md] + SKILL --> RFS[filter-search-matrix.md] + SKILL --> RHK[harness-knowledge.md] + SKILL --> RC[config.md] + SKILL --> ROQ[open-questions.md] + SKILL --> AG2[agents/diagnostics-analyzer.md] + SKILL --> AG3[borrowed: ai-engineer — canonical in mutagent-builder] + SKILL --> AG4[borrowed: ai-architect — canonical in mutagent-builder] + + RW1 --> RS[source-platforms/*.md] + RW1 --> RT[target-platforms/*.md] + RW0 --> RW2 + RW0 --> RW4 + RW2 --> RW4 + RW2 --> RS + RW3 --> RT + + RS -.->|hyperlinks| EXT1[Upstream platform docs] + RT -.->|hyperlinks| EXT2[Upstream platform docs] + + AG2 --> RW2 + AG3 --> RW3 + + T0[scripts/tier0-scan.ts] --> NT[scripts/normalize/trace.ts] + SL[scripts/slicer.ts] --> NT + EC[scripts/normalize/platforms/entity-context.ts] --> NT + EN[scripts/enrich/build-render-input.ts] --> NT + EN --> RR + RR[scripts/report/render.ts] --> RHT[assets/templates/report.html.tpl] + CT[scripts/contract/types.ts] --> RR + CL[scripts/config/load.ts] --> CS[scripts/config/schema.ts] + CV[scripts/config/validate.ts] --> CS + SD[scripts/setup/detect.ts] --> CL + SD --> CV + NPL[scripts/normalize/platforms/*.ts] --> NT + NPL --> EC +``` + +## Table of Contents + +| Reference | Purpose | +|-----------|---------| +| `overview.md` | **Entry point for new users** — What/when/quick-start/glossary (PRD-SO-01) | +| `principles.md` | 53 Design Principles — PR-001 to PR-053 | +| `operator-feedback-log.md` | Append-only operator feedback on the report shape (Wave-5 R1.6) — the durable WHY behind the gold-standard renderer | +| `operation-inventory.md` | Type A/B/C operation classification | +| `adapter-strategy.md` | Adapter Q1-Q6 locked decisions | +| `filter-search-matrix.md` | Per-platform Filter/Search coverage matrix | +| `harness-knowledge.md` | Platform Knowledge Table (expandable) | +| `config.md` | Config schema with doc strings | +| `open-questions.md` | OQ-1..OQ-10 all resolved | +| `workflows/onboarding.md` | 8-phase onboarding procedure | +| `workflows/orchestrator-protocol.md` | Inline orchestrator protocol (parent session); Step 8.5 builds the render input via the enricher | +| `workflows/diagnostics.md` | Full diagnostic procedure + NL→filter | +| `workflows/rca.md` | RCA layer procedure + 3-dim taxonomy | +| `workflows/verification-methodology.md` | Background Investigator finding false-positive audit (5 tiers + AuditVerdict + per-source cache-detection); on-demand, improvable | +| `workflows/rendering-anatomy.md` | Canonical per-finding + per-remedy panel anatomy (PRD-CC-12) | +| `workflows/schedule-prep.md` | How to wire scheduling post-v0.1 | +| `source-platforms/langfuse.md` | Langfuse CLI fetch + filter examples | +| `source-platforms/otel.md` | OpenTelemetry OTLP pull + queries | +| `source-platforms/local-jsonl.md` | Local JSONL file read patterns | +| `source-platforms/claude-code-transcripts.md` | Claude Code session transcript format | +| `source-platforms/codex-transcripts.md` | Codex session transcript format | +| `target-platforms/local-claude.md` | .claude/agents/*.md apply recipe | +| `target-platforms/local-codex.md` | .codex/agents/*.md apply recipe | +| `target-platforms/local-cursor.md` | Cursor agent dir apply | +| `target-platforms/local-opencode.md` | OpenCode agent dir apply | +| `target-platforms/local-mastra.md` | Mastra code-construct apply | +| `target-platforms/local-cloud-agent-sdk.md` | Cloud Agent SDK apply | +| `target-platforms/cloud-rest.md` | REST PUT with idempotency | +| `internal/self-diagnostics.md` | [INTERNAL] PR-022 self-diagnostics playbook | diff --git a/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/script-index.md b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/script-index.md new file mode 100644 index 00000000..c81ef971 --- /dev/null +++ b/submissions/localhost-3000/.agents/skills/mutagent-diagnostics/references/script-index.md @@ -0,0 +1,101 @@ +# Script Index — the data-flow navigation map + +> **Why this file exists (W13).** Most recurring report bugs are *forgotten data*: a +> producer runs but its output is never threaded into `runMeta`, or the renderer +> dereferences a field no producer guaranteed → `undefined` in the HTML. This index is +> the single place the orchestrator (and any maintainer) reads to know **what every +> script consumes, produces, and which `runMeta`/render field depends on it.** If you +> add a step, add its row here. The **gates** column is what FAILS LOUD if the data is +> forgotten — never rely on memory; the gate is the enforcement. +> +> Quick listing at runtime: `bash scripts/cli/run.sh --list` (or read this file). + +## Run sequence → script → I/O → the field it feeds → the gate that enforces it + +> **Form column (REQ-051).** Every operation is exactly one of ①**script / +> code-workflow** · ②**agent-workflow** · ③**hybrid** (legend + integrity rule in +> "Operation forms (REQ-051)" below). ②-form steps (e.g. Step 2, Step 3) produce +> TYPED outputs and are legitimate — a "no script" cell is NOT a coverage gap. + +| Step | Form | Script | Consumes | Produces | Threads into `runMeta` / render | Enforced by | +|------|------|--------|----------|----------|----------------------------------|-------------| +| 2 | ②agent-workflow | *(no script)* — `Bash( scores list)` + LLM classify | platform score samples | **scale type** (`boolean`\|`discrete-1-5`\|…) — TYPED | informs Step 3 `scoreBelow` threshold | AskUserQuestion on ambiguity | +| 3 | ②agent-workflow | *(no script)* — LLM NL→filter reasoning | operator NL query + scale type | **`TraceFilter`** (agentId/time/hasFeedback/scoreBelow) — TYPED | parameterizes the UPSTREAM `mutagent-cli trace fetch --export` query (Helix pre-stage) | filter-search-matrix per-platform flags | +| 3a | ①script | `scripts/invocation/parse-brief.ts` | operator brief (string) | `{agent,timeWindow,focus,residual,scopeType,entity}` | `runMeta.operatorInvocation` (verbatim, D2) | parse-brief.test | +| 3.5 | ③hybrid | `scripts/awareness/llm-sample.ts` + `blind-spots.ts` | 5 representative traces | `AwarenessSample`, `BlindSpots` | `runMeta.awarenessSample` · `runMeta.blindSpots` (F2) | completeness-check · wave6-checklist | +| 3.7 | ①script | `scripts/normalize/read-unitf.ts` (+ `unitf-adapter.ts`) — reads the handed-over UniTF JSONL (+ manifest) from `HandoverBundle.inputs[]`; fetch+normalize now upstream in `@mutagent/tools` | UniTF JSONL (one `UnifiedTrace`/line) + optional `manifest.json` | `TraceMetadata[]`, `EntityContext` (deterministic, no LLM) — projected from `ut.*` + `ut.ext.agent` | `diagnosedEntity` · `billedTokens` · trace latency (span-authoritative, W13-D2) · **GROUNDED cache fields** (W18-cache: `cachedInputTokens` · `cacheCreationTokens` · `cacheStatus` `hit`\|`miss`\|`unknown` · `cacheHitRate`) — carried in `ut.tokens`/`ut.ext.cache`; absent ⇒ `unknown`, NEVER inferred from flat `promptTokens` | findings-contract (entity) · render-contract pass | +| 4 | ①script | `scripts/tier0-scan.ts` | `TraceMetadata[]` | `Tier0Report` (errorSpike/latencySpike/feedbackCluster/estimatedSlots) | signal census candidates | tier0 tests | +| 4.5 | ①script | `scripts/library/match.ts` | Tier0Report + entity | `libraryMatches[]` (3× weight) · double-zero gate | `runMeta.decisions` (if empty) | double-zero fail-loud | +| 5 | ①script | `scripts/slicer.ts` · `scripts/sample/representative.ts` | Tier0Report + metadata | slices · `sample` + `CoverageProof` (worst-weighted, W13-D9) | per-finding `coverageProof` (W12-13) | representative.test | +| 5c | ①script | `scripts/scan/objection.ts` | trace bodies (user-authored text) | `ObjectionScanResult` (`byTrace`, `objectionRate`) — deterministic, NO LLM | **sampling-priority hint only** — NOT a census signal (advisory pre-filter; may corroborate a deep-read finding) | objection.test | +| 5.7 | ①script | `scripts/context/build-diagnosis-context.ts` (CLI: `--entity-context --traces --output [--purpose ] [--doc