@mmerterden/multi-agent-pipeline 12.6.0 → 12.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +209 -0
- package/README.md +18 -18
- package/docs/FIGMA_PIPELINE.md +34 -34
- package/docs/adr/0001-three-model-triage.md +12 -12
- package/docs/adr/0002-instruction-driven-flag.md +5 -5
- package/docs/adr/0003-unified-shared-skills.md +5 -5
- package/docs/adr/0004-zero-dependency-philosophy.md +5 -5
- package/docs/adr/0005-lazy-phase-docs.md +2 -2
- package/docs/adr/0006-skills-core-external-split.md +6 -6
- package/docs/adr/0007-multi-tool-adapter-framework.md +19 -19
- package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +19 -19
- package/docs/adr/README.md +1 -1
- package/docs/best-practices.md +3 -3
- package/docs/features.md +28 -28
- package/docs/performance.md +16 -16
- package/docs/recovery-guide.md +39 -39
- package/index.js +4 -4
- package/install/_common.mjs +53 -11
- package/install/_copilot-instructions.mjs +2 -2
- package/install/_dev-only-files.mjs +126 -6
- package/install/_platform-filter.mjs +1 -1
- package/install/_telemetry.mjs +1 -1
- package/install/claude.mjs +20 -13
- package/install/copilot.mjs +11 -23
- package/install/index.mjs +7 -15
- package/install/templates/copilot-instructions.md +54 -54
- package/install.js +1 -1
- package/package.json +29 -11
- package/pipeline/commands/multi-agent/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/analysis/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/create-jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/design-check/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/diff-explain/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/finish/SKILL.md +6 -6
- package/pipeline/commands/multi-agent/forget/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/help/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/issue/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/kill/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/language/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/log/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/manual-test/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/prune-logs/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/purge/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/refactor/SKILL.md +16 -8
- package/pipeline/commands/multi-agent/resume/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/review/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review-issue/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/review-jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/routines/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/save/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/scan/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/search/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/setup/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/stack/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/status/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/sync/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/test/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/update/SKILL.md +3 -3
- package/pipeline/lib/account-resolver.sh +1 -1
- package/pipeline/lib/channels-multi-repo.sh +1 -1
- package/pipeline/lib/context-link-extractor.sh +1 -1
- package/pipeline/lib/credential-store.sh +21 -1
- package/pipeline/lib/fetch-confluence.sh +1 -1
- package/pipeline/lib/fetch-crashlytics.sh +1 -1
- package/pipeline/lib/fetch-fortify.sh +1 -1
- package/pipeline/lib/fetch-graylog.sh +1 -1
- package/pipeline/lib/fetch-swagger.sh +1 -1
- package/pipeline/lib/issue-fetcher.sh +1 -1
- package/pipeline/lib/multi-repo-pipeline.sh +1 -1
- package/pipeline/lib/repo-cache.sh +1 -1
- package/pipeline/lib/submodule-detector.sh +1 -1
- package/pipeline/multi-agent-refs/_account-picker.md +1 -1
- package/pipeline/multi-agent-refs/_dev-context.md +1 -1
- package/pipeline/multi-agent-refs/_repo-picker.md +1 -1
- package/pipeline/multi-agent-refs/component-dispatch.md +1 -1
- package/pipeline/multi-agent-refs/component-generation.md +121 -0
- package/pipeline/multi-agent-refs/cross-cli-contract.md +1 -1
- package/pipeline/multi-agent-refs/features/model-fallback.md +2 -2
- package/pipeline/multi-agent-refs/phases/operations.md +28 -0
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -0
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +1 -2
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +50 -5
- package/pipeline/preferences-template.json +5 -11
- package/pipeline/schemas/agent-state.schema.json +39 -9
- package/pipeline/schemas/analysis-output.schema.json +18 -4
- package/pipeline/schemas/analysis-spec.schema.json +120 -32
- package/pipeline/schemas/clarify-output.schema.json +15 -5
- package/pipeline/schemas/design-check-config.schema.json +32 -11
- package/pipeline/schemas/dev-critic-output.schema.json +20 -5
- package/pipeline/schemas/figma-project-config.schema.json +42 -10
- package/pipeline/schemas/learnings-ledger.schema.json +10 -2
- package/pipeline/schemas/migrations/figma-config-1.0.0-to-2.0.0.mjs +1 -4
- package/pipeline/schemas/migrations/prefs-2.0.0-to-2.1.0.mjs +24 -7
- package/pipeline/schemas/plan-todos.schema.json +6 -3
- package/pipeline/schemas/planning-output.schema.json +5 -1
- package/pipeline/schemas/prefs.schema.json +97 -229
- package/pipeline/schemas/test-gap.schema.json +5 -5
- package/pipeline/schemas/token-budget.json +8 -8
- package/pipeline/schemas/triage-corpus.schema.json +1 -1
- package/pipeline/scripts/_smoke-root.sh +61 -0
- package/pipeline/scripts/aggregate-metrics.mjs +18 -6
- package/pipeline/scripts/audit-log.sh +25 -0
- package/pipeline/scripts/build-skills-index.mjs +6 -2
- package/pipeline/scripts/build-stack-plugins.mjs +142 -39
- package/pipeline/scripts/check-derived-drift.mjs +196 -0
- package/pipeline/scripts/classify-plan-safety.mjs +20 -7
- package/pipeline/scripts/cost-budget-check.mjs +2 -1
- package/pipeline/scripts/cost-table.json +1 -1
- package/pipeline/scripts/diff-explain.mjs +7 -3
- package/pipeline/scripts/diff-risk-score.mjs +13 -3
- package/pipeline/scripts/evidence-gate.mjs +7 -2
- package/pipeline/scripts/gen-mode-dispatch.mjs +38 -21
- package/pipeline/scripts/gen-skills-index.mjs +18 -3
- package/pipeline/scripts/learning-curve.mjs +13 -3
- package/pipeline/scripts/learnings-ledger.mjs +103 -36
- package/pipeline/scripts/localize-commands.mjs +6 -1
- package/pipeline/scripts/match-skills.mjs +15 -4
- package/pipeline/scripts/migrate-prefs.mjs +33 -16
- package/pipeline/scripts/phase-tracker.sh +3 -1
- package/pipeline/scripts/repo-map.mjs +110 -64
- package/pipeline/scripts/review-scope.mjs +7 -1
- package/pipeline/scripts/routine-registry.mjs +4 -9
- package/pipeline/scripts/run-aggregator.mjs +11 -5
- package/pipeline/scripts/run-metrics.mjs +13 -8
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +21 -7
- package/pipeline/scripts/test-gap-scan.mjs +44 -12
- package/pipeline/scripts/test-integrity-gate.mjs +5 -1
- package/pipeline/scripts/token-budget-report.mjs +44 -21
- package/pipeline/scripts/triage-memory.mjs +126 -34
- package/pipeline/scripts/uninstall.mjs +74 -30
- package/pipeline/scripts/validate-analysis-doc.mjs +15 -5
- package/pipeline/scripts/validate-diff-risk.mjs +32 -18
- package/pipeline/scripts/validate-test-gap.mjs +17 -7
- package/pipeline/scripts/validate-triage.mjs +17 -5
- package/pipeline/scripts/write-state.mjs +32 -9
- package/pipeline/skills/.skills-index.json +91 -91
- package/pipeline/skills/shared/README.md +57 -57
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +1 -1
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +26 -279
- package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-finish/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +16 -8
- package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +3 -3
- package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +1 -1
- package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +1 -1
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -4
- package/pipeline/skills/shared/external/agentflow/SKILL.md +1 -1
- package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/android_ui_verification/SKILL.md +1 -1
- package/pipeline/skills/shared/external/api-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +1 -1
- package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +1 -1
- package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +12 -12
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -1
- package/pipeline/skills/shared/external/context-compression/SKILL.md +1 -1
- package/pipeline/skills/shared/external/council/SKILL.md +3 -3
- package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -1
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +1 -1
- package/pipeline/skills/shared/external/docker-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +1 -1
- package/pipeline/skills/shared/external/firebase/SKILL.md +1 -1
- package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +1 -1
- package/pipeline/skills/shared/external/help-skills/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-content/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-status/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-components-system/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-foundations/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-inputs/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-platforms/SKILL.md +1 -1
- package/pipeline/skills/shared/external/hig-technologies/SKILL.md +1 -1
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -1
- package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-developer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +1 -1
- package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +1 -1
- package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +1 -1
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -1
- package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/observability-engineer/SKILL.md +1 -1
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -1
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -1
- package/pipeline/skills/shared/external/search-first/SKILL.md +2 -2
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +12 -12
- package/pipeline/skills/shared/external/skill-creator/audit.md +21 -21
- package/pipeline/skills/shared/external/skill-creator/checklist.md +3 -3
- package/pipeline/skills/shared/external/skill-creator/examples.md +10 -10
- package/pipeline/skills/shared/external/skill-creator/label-check.md +17 -17
- package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +86 -50
- package/pipeline/skills/shared/external/skill-creator/template.md +9 -9
- package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +1 -1
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -1
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -1
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -1
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -1
- package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -1
- package/pipeline/skills/shared/external/xcode-build-benchmark/schemas/build-benchmark.schema.json +9 -49
- package/pipeline/skills/skills-index.md +57 -57
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-2-plan.json +0 -30
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/01-ios-bugfix-darkmode/task.json +0 -12
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-2-plan.json +0 -43
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-review.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/expected/phase-4-triage.json +0 -35
- package/pipeline/eval/golden-tasks/02-android-feature-compose/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/02-android-feature-compose/task.json +0 -12
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/03-backend-python-ratelimit/task.json +0 -12
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-2-plan.json +0 -40
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-review.json +0 -20
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/expected/phase-4-triage.json +0 -15
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/04-frontend-next-hydration/task.json +0 -12
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/05-ios-security-keychain/task.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-2-plan.json +0 -41
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/expected/phase-4-triage.json +0 -6
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/06-android-refactor-usecase/task.json +0 -12
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-1-analysis.json +0 -29
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-2-plan.json +0 -42
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-review.json +0 -28
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/expected/phase-4-triage.json +0 -27
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/07-backend-node-idempotency/task.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-1-analysis.json +0 -25
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-2-plan.json +0 -31
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-review.json +0 -12
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/expected/phase-4-triage.json +0 -18
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/metadata.json +0 -14
- package/pipeline/eval/golden-tasks/08-ios-auth-consensus-unverified/task.json +0 -12
- package/pipeline/eval/golden-tasks/README.md +0 -65
- package/pipeline/eval/intent-cases.json +0 -40
- package/pipeline/eval/run-metrics-fixture.json +0 -46
- package/pipeline/eval/triage/01-empty-findings/expected.json +0 -6
- package/pipeline/eval/triage/01-empty-findings/input.json +0 -5
- package/pipeline/eval/triage/01-empty-findings/notes.md +0 -7
- package/pipeline/eval/triage/02-real-blocker/expected.json +0 -15
- package/pipeline/eval/triage/02-real-blocker/input.json +0 -14
- package/pipeline/eval/triage/02-real-blocker/notes.md +0 -7
- package/pipeline/eval/triage/03-out-of-scope-defer/expected.json +0 -18
- package/pipeline/eval/triage/03-out-of-scope-defer/input.json +0 -14
- package/pipeline/eval/triage/03-out-of-scope-defer/notes.md +0 -10
- package/pipeline/eval/triage/04-false-positive-reject/expected.json +0 -18
- package/pipeline/eval/triage/04-false-positive-reject/input.json +0 -14
- package/pipeline/eval/triage/04-false-positive-reject/notes.md +0 -10
- package/pipeline/eval/triage/05-mixed-classification/expected.json +0 -43
- package/pipeline/eval/triage/05-mixed-classification/input.json +0 -38
- package/pipeline/eval/triage/05-mixed-classification/notes.md +0 -17
- package/pipeline/eval/triage/06-severity-mismatch/expected.json +0 -15
- package/pipeline/eval/triage/06-severity-mismatch/input.json +0 -14
- package/pipeline/eval/triage/06-severity-mismatch/notes.md +0 -9
- package/pipeline/eval/triage/07-duplicate-reviewers/expected.json +0 -27
- package/pipeline/eval/triage/07-duplicate-reviewers/input.json +0 -22
- package/pipeline/eval/triage/07-duplicate-reviewers/notes.md +0 -9
- package/pipeline/eval/triage/08-style-misclassified/expected.json +0 -18
- package/pipeline/eval/triage/08-style-misclassified/input.json +0 -14
- package/pipeline/eval/triage/08-style-misclassified/notes.md +0 -9
- package/pipeline/eval/triage/09-cascading-finding/expected.json +0 -23
- package/pipeline/eval/triage/09-cascading-finding/input.json +0 -22
- package/pipeline/eval/triage/09-cascading-finding/notes.md +0 -9
- package/pipeline/eval/triage/10-deferred-crossref/expected.json +0 -18
- package/pipeline/eval/triage/10-deferred-crossref/input.json +0 -14
- package/pipeline/eval/triage/10-deferred-crossref/notes.md +0 -9
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/expected.json +0 -27
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/input.json +0 -22
- package/pipeline/eval/triage/11-vercel-token-leak-blocker/notes.md +0 -14
- package/pipeline/eval/triage/README.md +0 -54
- package/pipeline/scripts/benchmark-phase-0.sh +0 -128
- package/pipeline/scripts/check-md-links.mjs +0 -84
- package/pipeline/scripts/eval-golden-tasks-live.mjs +0 -297
- package/pipeline/scripts/eval-golden-tasks.mjs +0 -212
- package/pipeline/scripts/eval-intent.mjs +0 -103
- package/pipeline/scripts/eval-mine-corpus.mjs +0 -201
- package/pipeline/scripts/eval-triage.mjs +0 -171
- package/pipeline/scripts/fixtures/diff-risk-android.diff +0 -40
- package/pipeline/scripts/fixtures/diff-risk-ios.diff +0 -48
- package/pipeline/scripts/fixtures/diff-risk-test-removal.diff +0 -40
- package/pipeline/scripts/fixtures/install-layout.tsv +0 -19
- package/pipeline/scripts/fixtures/pack-expected-count.txt +0 -1
- package/pipeline/scripts/fixtures/test-gap-node.diff +0 -30
- package/pipeline/scripts/fixtures/test-gap-python.diff +0 -32
- package/pipeline/scripts/lint-mcp-refs.mjs +0 -207
- package/pipeline/scripts/lint-skills.mjs +0 -143
- package/pipeline/scripts/run-smokes.mjs +0 -76
- package/pipeline/scripts/smoke-add-detail.sh +0 -137
- package/pipeline/scripts/smoke-agent-guard.sh +0 -74
- package/pipeline/scripts/smoke-agent-log-cost.sh +0 -262
- package/pipeline/scripts/smoke-agent-model-routing.sh +0 -87
- package/pipeline/scripts/smoke-ask-choice.sh +0 -42
- package/pipeline/scripts/smoke-autopilot-circuit-breaker.sh +0 -36
- package/pipeline/scripts/smoke-bitbucket-contract.sh +0 -255
- package/pipeline/scripts/smoke-changelog-version.sh +0 -47
- package/pipeline/scripts/smoke-channels-approval-gate.sh +0 -60
- package/pipeline/scripts/smoke-channels-flow.sh +0 -130
- package/pipeline/scripts/smoke-ci-workflows.sh +0 -88
- package/pipeline/scripts/smoke-clarify.sh +0 -148
- package/pipeline/scripts/smoke-command-inventory.sh +0 -81
- package/pipeline/scripts/smoke-commands-skills-parity.sh +0 -87
- package/pipeline/scripts/smoke-community-gates.sh +0 -75
- package/pipeline/scripts/smoke-compliance-skills.sh +0 -119
- package/pipeline/scripts/smoke-config-hygiene.sh +0 -58
- package/pipeline/scripts/smoke-cost-budget.sh +0 -70
- package/pipeline/scripts/smoke-cost-summary.sh +0 -139
- package/pipeline/scripts/smoke-cross-phase-cohesion.sh +0 -128
- package/pipeline/scripts/smoke-description-tr.sh +0 -82
- package/pipeline/scripts/smoke-dev-critic.sh +0 -144
- package/pipeline/scripts/smoke-diff-explain.sh +0 -147
- package/pipeline/scripts/smoke-diff-risk.sh +0 -190
- package/pipeline/scripts/smoke-dynamic-skill-loading.sh +0 -160
- package/pipeline/scripts/smoke-eval-live.sh +0 -136
- package/pipeline/scripts/smoke-evidence-gate.sh +0 -93
- package/pipeline/scripts/smoke-extract-conventions.sh +0 -163
- package/pipeline/scripts/smoke-fetchers-offline.sh +0 -448
- package/pipeline/scripts/smoke-figma-dispatch.sh +0 -112
- package/pipeline/scripts/smoke-gate-hooks.sh +0 -74
- package/pipeline/scripts/smoke-gc-tmp.sh +0 -130
- package/pipeline/scripts/smoke-gc-worktrees.sh +0 -125
- package/pipeline/scripts/smoke-generate-issue.sh +0 -120
- package/pipeline/scripts/smoke-handoff-contract.sh +0 -92
- package/pipeline/scripts/smoke-identity-isolation.sh +0 -70
- package/pipeline/scripts/smoke-install-layout.sh +0 -248
- package/pipeline/scripts/smoke-intent-guard.sh +0 -86
- package/pipeline/scripts/smoke-issue-comment-template.sh +0 -86
- package/pipeline/scripts/smoke-issue-jira-triad.sh +0 -120
- package/pipeline/scripts/smoke-keychain.sh +0 -158
- package/pipeline/scripts/smoke-language-axis.sh +0 -109
- package/pipeline/scripts/smoke-learning-curve.sh +0 -61
- package/pipeline/scripts/smoke-learnings-ledger.sh +0 -86
- package/pipeline/scripts/smoke-lib-scripts.sh +0 -448
- package/pipeline/scripts/smoke-mcp-gate.sh +0 -68
- package/pipeline/scripts/smoke-md-links.sh +0 -8
- package/pipeline/scripts/smoke-md2confluence.sh +0 -126
- package/pipeline/scripts/smoke-metrics-cache-ratio.sh +0 -72
- package/pipeline/scripts/smoke-migrate-state.sh +0 -102
- package/pipeline/scripts/smoke-mode-dispatch-drift.sh +0 -161
- package/pipeline/scripts/smoke-model-fallback.sh +0 -89
- package/pipeline/scripts/smoke-multi-repo-integration.sh +0 -116
- package/pipeline/scripts/smoke-multi-repo-worktree.sh +0 -61
- package/pipeline/scripts/smoke-no-mcp-in-dev-phases.sh +0 -115
- package/pipeline/scripts/smoke-no-token-prompt.sh +0 -85
- package/pipeline/scripts/smoke-pack-contents.sh +0 -140
- package/pipeline/scripts/smoke-pat-audit.sh +0 -128
- package/pipeline/scripts/smoke-per-repo-memory.sh +0 -156
- package/pipeline/scripts/smoke-phase-0-multi-repo.sh +0 -170
- package/pipeline/scripts/smoke-phase-6-multi.sh +0 -79
- package/pipeline/scripts/smoke-phase-banner.sh +0 -101
- package/pipeline/scripts/smoke-phase-tracker.sh +0 -324
- package/pipeline/scripts/smoke-phase0-bridge-contract.sh +0 -241
- package/pipeline/scripts/smoke-phase4-gates.sh +0 -45
- package/pipeline/scripts/smoke-phase4-triage.sh +0 -229
- package/pipeline/scripts/smoke-plan-approval-gate.sh +0 -71
- package/pipeline/scripts/smoke-plan-safety.sh +0 -139
- package/pipeline/scripts/smoke-plan-todos.sh +0 -196
- package/pipeline/scripts/smoke-plugin-validate.sh +0 -64
- package/pipeline/scripts/smoke-pr-review-actions.sh +0 -152
- package/pipeline/scripts/smoke-pre-commit.sh +0 -170
- package/pipeline/scripts/smoke-pref-migration.sh +0 -226
- package/pipeline/scripts/smoke-prefs-language.sh +0 -134
- package/pipeline/scripts/smoke-progress-contract.sh +0 -127
- package/pipeline/scripts/smoke-prune-logs.sh +0 -137
- package/pipeline/scripts/smoke-purge.sh +0 -138
- package/pipeline/scripts/smoke-push-retry.sh +0 -75
- package/pipeline/scripts/smoke-repo-map.sh +0 -300
- package/pipeline/scripts/smoke-review-readiness.sh +0 -92
- package/pipeline/scripts/smoke-review-watch.sh +0 -146
- package/pipeline/scripts/smoke-routines.sh +0 -84
- package/pipeline/scripts/smoke-run-aggregator.sh +0 -216
- package/pipeline/scripts/smoke-run-metrics.sh +0 -50
- package/pipeline/scripts/smoke-search.sh +0 -187
- package/pipeline/scripts/smoke-shadow-git.sh +0 -224
- package/pipeline/scripts/smoke-skill-authoring.sh +0 -137
- package/pipeline/scripts/smoke-skill-language.sh +0 -83
- package/pipeline/scripts/smoke-skill-manifest.sh +0 -138
- package/pipeline/scripts/smoke-skill-scan.sh +0 -198
- package/pipeline/scripts/smoke-source-parity.sh +0 -85
- package/pipeline/scripts/smoke-subagent-validators.sh +0 -108
- package/pipeline/scripts/smoke-sync-parity.sh +0 -92
- package/pipeline/scripts/smoke-tasklist-ordering.sh +0 -112
- package/pipeline/scripts/smoke-telemetry.sh +0 -147
- package/pipeline/scripts/smoke-test-gap.sh +0 -183
- package/pipeline/scripts/smoke-token-budget.sh +0 -67
- package/pipeline/scripts/smoke-token-preflight.sh +0 -82
- package/pipeline/scripts/smoke-tracker-contract.sh +0 -191
- package/pipeline/scripts/smoke-tracker-tokens-invocation.sh +0 -73
- package/pipeline/scripts/smoke-triage-memory.sh +0 -174
- package/pipeline/scripts/smoke-update-check.sh +0 -135
- package/pipeline/scripts/smoke-url-enrichment.sh +0 -70
- package/pipeline/scripts/smoke-validate-analysis-doc.sh +0 -161
- package/pipeline/scripts/smoke-validator-contradiction.sh +0 -67
- package/pipeline/scripts/smoke-validator-gates.sh +0 -164
- package/pipeline/scripts/smoke-vercel-deploy-redact.sh +0 -129
- package/pipeline/scripts/smoke-verify-by-test.sh +0 -148
- package/pipeline/scripts/smoke-wiki-integration.sh +0 -122
- package/pipeline/scripts/smoke-work-summary.sh +0 -163
- package/pipeline/scripts/smoke-workflow-audit.sh +0 -69
- package/pipeline/scripts/smoke-worktree-path-convention.sh +0 -86
- package/pipeline/scripts/smoke-wrapper-preservation.sh +0 -68
- package/pipeline/scripts/smoke-write-state.sh +0 -115
- package/pipeline/scripts/sync-parity-check.sh +0 -135
- package/pipeline/scripts/test-gap-rules/android.json +0 -25
- package/pipeline/scripts/test-gap-rules/ios.json +0 -29
- package/pipeline/scripts/test-gap-rules/node.json +0 -17
- package/pipeline/scripts/test-gap-rules/python.json +0 -19
- package/pipeline/scripts/validate-schemas.mjs +0 -88
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# smoke-no-mcp-in-dev-phases.sh
|
|
4
|
-
#
|
|
5
|
-
# Gate: pipeline run telemetry must not contain MCP calls outside Phase 1
|
|
6
|
-
# (Analysis). Per Locked decision 30, MCP usage is permitted only during
|
|
7
|
-
# Phase 1; any entry in state.telemetry.mcpCalls[] with phase >= 2 is a
|
|
8
|
-
# violation.
|
|
9
|
-
#
|
|
10
|
-
# Inputs
|
|
11
|
-
# --state-file <path> Optional override (default: ~/.claude/state/run/latest.json)
|
|
12
|
-
#
|
|
13
|
-
# Outcomes
|
|
14
|
-
# - State file missing -> WARN, exit 0 (no run to check)
|
|
15
|
-
# - telemetry.mcpCalls field absent -> PASS, exit 0 (older run, no telemetry)
|
|
16
|
-
# - All entries phase < 2 -> PASS, exit 0
|
|
17
|
-
# - One or more violations -> FAIL summary on stdout, exit 1
|
|
18
|
-
#
|
|
19
|
-
# stdout: human-readable summary only. stderr: empty in normal operation.
|
|
20
|
-
|
|
21
|
-
set -euo pipefail
|
|
22
|
-
|
|
23
|
-
STATE_FILE="${HOME}/.claude/state/run/latest.json"
|
|
24
|
-
|
|
25
|
-
while [ "$#" -gt 0 ]; do
|
|
26
|
-
case "$1" in
|
|
27
|
-
--state-file)
|
|
28
|
-
shift
|
|
29
|
-
if [ "$#" -eq 0 ]; then
|
|
30
|
-
echo "FAIL: --state-file requires a path argument"
|
|
31
|
-
exit 2
|
|
32
|
-
fi
|
|
33
|
-
STATE_FILE="$1"
|
|
34
|
-
shift
|
|
35
|
-
;;
|
|
36
|
-
--state-file=*)
|
|
37
|
-
STATE_FILE="${1#--state-file=}"
|
|
38
|
-
shift
|
|
39
|
-
;;
|
|
40
|
-
-h|--help)
|
|
41
|
-
echo "Usage: $0 [--state-file <path>]"
|
|
42
|
-
echo ""
|
|
43
|
-
echo "Default state file: ~/.claude/state/run/latest.json"
|
|
44
|
-
exit 0
|
|
45
|
-
;;
|
|
46
|
-
*)
|
|
47
|
-
echo "FAIL: unknown argument: $1"
|
|
48
|
-
exit 2
|
|
49
|
-
;;
|
|
50
|
-
esac
|
|
51
|
-
done
|
|
52
|
-
|
|
53
|
-
if ! command -v jq >/dev/null 2>&1; then
|
|
54
|
-
echo "FAIL: jq is required but not installed"
|
|
55
|
-
exit 2
|
|
56
|
-
fi
|
|
57
|
-
|
|
58
|
-
if [ ! -f "$STATE_FILE" ]; then
|
|
59
|
-
echo "WARN: state file not found at $STATE_FILE - no run to check"
|
|
60
|
-
exit 0
|
|
61
|
-
fi
|
|
62
|
-
|
|
63
|
-
# Validate JSON parse first; corrupt state cannot be silently passed.
|
|
64
|
-
if ! jq empty "$STATE_FILE" >/dev/null 2>&1; then
|
|
65
|
-
echo "FAIL: state file is not valid JSON: $STATE_FILE"
|
|
66
|
-
exit 2
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
# If telemetry.mcpCalls is absent or not an array, this is an older state
|
|
70
|
-
# format that did not record MCP usage. PASS by contract.
|
|
71
|
-
HAS_FIELD=$(jq -r '
|
|
72
|
-
if (.telemetry // empty) | type == "object"
|
|
73
|
-
then
|
|
74
|
-
if (.telemetry.mcpCalls // empty) | type == "array" then "yes" else "no" end
|
|
75
|
-
else "no" end
|
|
76
|
-
' "$STATE_FILE")
|
|
77
|
-
|
|
78
|
-
if [ "$HAS_FIELD" != "yes" ]; then
|
|
79
|
-
echo "PASS: telemetry.mcpCalls field absent - no MCP usage recorded"
|
|
80
|
-
exit 0
|
|
81
|
-
fi
|
|
82
|
-
|
|
83
|
-
# Count total entries and violations (phase >= 2).
|
|
84
|
-
TOTAL=$(jq -r '.telemetry.mcpCalls | length' "$STATE_FILE")
|
|
85
|
-
VIOLATIONS=$(jq -r '
|
|
86
|
-
.telemetry.mcpCalls
|
|
87
|
-
| map(select((.phase // 0) >= 2))
|
|
88
|
-
| length
|
|
89
|
-
' "$STATE_FILE")
|
|
90
|
-
|
|
91
|
-
if [ "$VIOLATIONS" -eq 0 ]; then
|
|
92
|
-
if [ "$TOTAL" -eq 0 ]; then
|
|
93
|
-
echo "PASS: no MCP calls outside Phase 1 (Analysis) - 0 entries"
|
|
94
|
-
else
|
|
95
|
-
echo "PASS: no MCP calls outside Phase 1 (Analysis) - ${TOTAL} entries, all in Phase 1"
|
|
96
|
-
fi
|
|
97
|
-
exit 0
|
|
98
|
-
fi
|
|
99
|
-
|
|
100
|
-
# Emit FAIL summary with up to first 5 offenders.
|
|
101
|
-
echo "FAIL: ${VIOLATIONS} MCP call(s) outside Phase 1 (Analysis) - Locked decision 30 violation"
|
|
102
|
-
echo ""
|
|
103
|
-
echo "First $([ "$VIOLATIONS" -lt 5 ] && echo "$VIOLATIONS" || echo 5) violation(s):"
|
|
104
|
-
|
|
105
|
-
jq -r '
|
|
106
|
-
.telemetry.mcpCalls
|
|
107
|
-
| map(select((.phase // 0) >= 2))
|
|
108
|
-
| .[0:5]
|
|
109
|
-
| .[]
|
|
110
|
-
| " FAIL: MCP call \(.tool // "<unknown>") in Phase \(.phase) at \(.timestamp // "<no timestamp>") - Locked decision 30 violation"
|
|
111
|
-
' "$STATE_FILE"
|
|
112
|
-
|
|
113
|
-
echo ""
|
|
114
|
-
echo "Total violations: ${VIOLATIONS} of ${TOTAL} entries"
|
|
115
|
-
exit 1
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# smoke-no-token-prompt.sh
|
|
4
|
-
#
|
|
5
|
-
# Asserts the pipeline never asks the user to type a token in chat. Tokens
|
|
6
|
-
# are resolved via credential-store.sh; missing/expired tokens trigger the
|
|
7
|
-
# Setup Wizard, not an inline prompt. See refs/keychain.md Rule 1.
|
|
8
|
-
#
|
|
9
|
-
# Greps shell scripts, markdown adapters, and orchestrator commands for
|
|
10
|
-
# hardcoded prompt patterns. Allowlist for legitimate setup wizard prompts.
|
|
11
|
-
|
|
12
|
-
set -euo pipefail
|
|
13
|
-
|
|
14
|
-
SELF_DIR=$(cd "$(dirname "$0")" && pwd)
|
|
15
|
-
PIPELINE_ROOT=$(cd "$SELF_DIR/.." && pwd)
|
|
16
|
-
|
|
17
|
-
cd "$PIPELINE_ROOT"
|
|
18
|
-
|
|
19
|
-
FAIL=0
|
|
20
|
-
|
|
21
|
-
# Pattern: anything that looks like the script asking for a token interactively.
|
|
22
|
-
# Acceptable: setup wizard explicitly tagged with `# allow: token-prompt`.
|
|
23
|
-
PATTERNS=(
|
|
24
|
-
"read -rp.*[Tt]oken"
|
|
25
|
-
"read -rp.*[Aa]pi.[Kk]ey"
|
|
26
|
-
"read -rp.*[Pp]aste.*token"
|
|
27
|
-
"read -rp.*[Ee]nter.*token"
|
|
28
|
-
'echo "Enter your.*[Tt]oken'
|
|
29
|
-
'echo "Paste.*[Tt]oken'
|
|
30
|
-
"AskUserQuestion.*[Tt]oken"
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
# Files in scope: shell scripts + adapter markdown.
|
|
34
|
-
TARGET_GLOB=(
|
|
35
|
-
"scripts/*.sh"
|
|
36
|
-
"scripts/*.mjs"
|
|
37
|
-
"multi-agent-refs/channels/*.md"
|
|
38
|
-
"multi-agent-refs/phases/*.md"
|
|
39
|
-
"commands/multi-agent/dev/SKILL.md"
|
|
40
|
-
"commands/multi-agent/dev-autopilot/SKILL.md"
|
|
41
|
-
"commands/multi-agent/autopilot/SKILL.md"
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
# Build a single grep invocation: all patterns via repeated -e flags,
|
|
45
|
-
# all target globs expanded once. Drops 7x7=49 grep subprocesses down to 1.
|
|
46
|
-
GREP_PATTERN_ARGS=()
|
|
47
|
-
for pattern in "${PATTERNS[@]}"; do
|
|
48
|
-
GREP_PATTERN_ARGS+=(-e "$pattern")
|
|
49
|
-
done
|
|
50
|
-
|
|
51
|
-
# Expand all target globs to actual paths once. Globs that don't match are
|
|
52
|
-
# silently dropped so the single grep call sees only existing files.
|
|
53
|
-
TARGET_PATHS=()
|
|
54
|
-
for glob in "${TARGET_GLOB[@]}"; do
|
|
55
|
-
for path in pipeline/$glob; do
|
|
56
|
-
[ -e "$path" ] && TARGET_PATHS+=("$path")
|
|
57
|
-
done
|
|
58
|
-
done
|
|
59
|
-
|
|
60
|
-
if [ "${#TARGET_PATHS[@]}" -gt 0 ]; then
|
|
61
|
-
while IFS= read -r match; do
|
|
62
|
-
[ -z "$match" ] && continue
|
|
63
|
-
file="${match%%:*}"
|
|
64
|
-
# Allowlist: setup.md and setup-related files explicitly handle token entry
|
|
65
|
-
# via the inline Token Save Flow (clipboard-based, not chat).
|
|
66
|
-
case "$file" in
|
|
67
|
-
*/setup.md|*setup-token-flow*|*credential-store*) continue ;;
|
|
68
|
-
esac
|
|
69
|
-
# Allowlist: explicit `# allow: token-prompt` annotation on the line.
|
|
70
|
-
case "$match" in
|
|
71
|
-
*'# allow: token-prompt'*) continue ;;
|
|
72
|
-
esac
|
|
73
|
-
echo "FAIL [smoke-no-token-prompt]: token prompt found in $file"
|
|
74
|
-
echo " $match"
|
|
75
|
-
FAIL=$((FAIL + 1))
|
|
76
|
-
done < <(grep -rEn "${GREP_PATTERN_ARGS[@]}" "${TARGET_PATHS[@]}" 2>/dev/null || true)
|
|
77
|
-
fi
|
|
78
|
-
|
|
79
|
-
if [ "$FAIL" -gt 0 ]; then
|
|
80
|
-
echo ""
|
|
81
|
-
echo "smoke-no-token-prompt: $FAIL violation(s). Tokens must be resolved via credential-store.sh; see refs/keychain.md Rule 1."
|
|
82
|
-
exit 1
|
|
83
|
-
fi
|
|
84
|
-
|
|
85
|
-
echo "smoke-no-token-prompt: ok"
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
#
|
|
3
|
-
# smoke-pack-contents.sh - guard what `npm publish` would actually ship.
|
|
4
|
-
#
|
|
5
|
-
# 1. Deny patterns: package.json files[] carries negations (`!...`) for
|
|
6
|
-
# dev-only / personal-data files. The published tarball must contain
|
|
7
|
-
# no file matching any of them. Patterns are read from package.json at
|
|
8
|
-
# runtime (via node), so the smoke never goes stale when the deny list
|
|
9
|
-
# changes.
|
|
10
|
-
# 2. File-count band: the total packed file count is compared against the
|
|
11
|
-
# committed fixture pipeline/scripts/fixtures/pack-expected-count.txt.
|
|
12
|
-
# Drift beyond +-15 percent fails - that magnitude means the files[]
|
|
13
|
-
# globs picked up (or dropped) a whole subtree, which deserves a human
|
|
14
|
-
# look. Refresh the fixture after reviewing:
|
|
15
|
-
# npm pack --dry-run --json 2>/dev/null \
|
|
16
|
-
# | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>console.log(JSON.parse(s)[0].files.length))' \
|
|
17
|
-
# > pipeline/scripts/fixtures/pack-expected-count.txt
|
|
18
|
-
# 3. publint (optional): linted via `npx --no-install` so it only runs
|
|
19
|
-
# when the package is already installed - never a network fetch.
|
|
20
|
-
#
|
|
21
|
-
# Exit codes: 0=pass, 1=violation, 2=environment broken
|
|
22
|
-
|
|
23
|
-
set -uo pipefail
|
|
24
|
-
|
|
25
|
-
REPO_ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
26
|
-
FIXTURE="$REPO_ROOT/pipeline/scripts/fixtures/pack-expected-count.txt"
|
|
27
|
-
|
|
28
|
-
command -v npm >/dev/null 2>&1 || { echo "FAIL: npm not on PATH"; exit 2; }
|
|
29
|
-
command -v node >/dev/null 2>&1 || { echo "FAIL: node not on PATH"; exit 2; }
|
|
30
|
-
|
|
31
|
-
PASS=0
|
|
32
|
-
FAIL=0
|
|
33
|
-
pass() { PASS=$((PASS + 1)); echo " ✓ $1"; }
|
|
34
|
-
fail() { FAIL=$((FAIL + 1)); echo " ✗ $1"; }
|
|
35
|
-
|
|
36
|
-
cleanup() { [ -n "${TMP:-}" ] && rm -rf "$TMP"; }
|
|
37
|
-
trap cleanup EXIT
|
|
38
|
-
TMP=$(mktemp -d)
|
|
39
|
-
|
|
40
|
-
# ──────────────────────────────────────────────────────────────────────────
|
|
41
|
-
echo "→ 1. npm pack --dry-run --json"
|
|
42
|
-
if ! (cd "$REPO_ROOT" && npm pack --dry-run --json 2>/dev/null > "$TMP/pack.json"); then
|
|
43
|
-
echo "FAIL: npm pack --dry-run failed"
|
|
44
|
-
exit 2
|
|
45
|
-
fi
|
|
46
|
-
|
|
47
|
-
# Deny check runs in node so the patterns come straight from package.json
|
|
48
|
-
# files[] negations - never hardcoded here.
|
|
49
|
-
cat > "$TMP/check.mjs" <<'MJS'
|
|
50
|
-
import { readFileSync } from "node:fs";
|
|
51
|
-
|
|
52
|
-
const [packJsonPath, pkgJsonPath] = process.argv.slice(2);
|
|
53
|
-
const packed = JSON.parse(readFileSync(packJsonPath, "utf-8"))[0].files.map((f) => f.path);
|
|
54
|
-
const files = JSON.parse(readFileSync(pkgJsonPath, "utf-8")).files || [];
|
|
55
|
-
const denies = files.filter((p) => p.startsWith("!")).map((p) => p.slice(1));
|
|
56
|
-
|
|
57
|
-
// Minimal glob -> regex: '**' spans path separators, '*' does not.
|
|
58
|
-
const toRegex = (glob) => {
|
|
59
|
-
const escaped = glob.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
60
|
-
const body = escaped
|
|
61
|
-
.split("**")
|
|
62
|
-
.map((part) => part.replace(/\*/g, "[^/]*"))
|
|
63
|
-
.join(".*");
|
|
64
|
-
return new RegExp("^" + body + "$");
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
const regexes = denies.map((d) => [d, toRegex(d)]);
|
|
68
|
-
let bad = 0;
|
|
69
|
-
for (const path of packed) {
|
|
70
|
-
for (const [glob, re] of regexes) {
|
|
71
|
-
if (re.test(path)) {
|
|
72
|
-
console.log(`DENY ${path} (matches !${glob})`);
|
|
73
|
-
bad++;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
console.log(`DENYCOUNT ${bad}`);
|
|
78
|
-
console.log(`PATTERNS ${denies.length}`);
|
|
79
|
-
console.log(`COUNT ${packed.length}`);
|
|
80
|
-
MJS
|
|
81
|
-
|
|
82
|
-
CHECK=$(node "$TMP/check.mjs" "$TMP/pack.json" "$REPO_ROOT/package.json")
|
|
83
|
-
COUNT=$(echo "$CHECK" | awk '/^COUNT /{print $2}')
|
|
84
|
-
DENYCOUNT=$(echo "$CHECK" | awk '/^DENYCOUNT /{print $2}')
|
|
85
|
-
PATTERNS=$(echo "$CHECK" | awk '/^PATTERNS /{print $2}')
|
|
86
|
-
|
|
87
|
-
if [ -z "$COUNT" ] || [ -z "$DENYCOUNT" ]; then
|
|
88
|
-
echo "FAIL: deny-pattern checker produced no result (node error?)"
|
|
89
|
-
exit 2
|
|
90
|
-
fi
|
|
91
|
-
|
|
92
|
-
pass "pack dry-run produced $COUNT files ($PATTERNS deny patterns loaded from package.json)"
|
|
93
|
-
|
|
94
|
-
# ──────────────────────────────────────────────────────────────────────────
|
|
95
|
-
echo "→ 2. deny patterns (files[] negations must not ship)"
|
|
96
|
-
if [ "$DENYCOUNT" -eq 0 ]; then
|
|
97
|
-
pass "no packed file matches a files[] negation"
|
|
98
|
-
else
|
|
99
|
-
fail "$DENYCOUNT packed file(s) match dev-only/personal-data exclusions:"
|
|
100
|
-
echo "$CHECK" | grep '^DENY ' | sed 's/^/ /'
|
|
101
|
-
fi
|
|
102
|
-
|
|
103
|
-
# ──────────────────────────────────────────────────────────────────────────
|
|
104
|
-
echo "→ 3. file-count band vs fixture (+-15 percent)"
|
|
105
|
-
if [ ! -f "$FIXTURE" ]; then
|
|
106
|
-
fail "fixture missing: $FIXTURE - create it from the refresh command in this script's header"
|
|
107
|
-
else
|
|
108
|
-
EXPECTED=$(tr -cd '0-9' < "$FIXTURE")
|
|
109
|
-
if [ -z "$EXPECTED" ] || [ "$EXPECTED" -eq 0 ]; then
|
|
110
|
-
fail "fixture unreadable or zero: $FIXTURE"
|
|
111
|
-
else
|
|
112
|
-
DIFF=$((COUNT - EXPECTED))
|
|
113
|
-
[ "$DIFF" -lt 0 ] && DIFF=$((-DIFF))
|
|
114
|
-
LIMIT=$((EXPECTED * 15 / 100))
|
|
115
|
-
if [ "$DIFF" -le "$LIMIT" ]; then
|
|
116
|
-
pass "count $COUNT within +-15 percent of expected $EXPECTED (drift $DIFF, limit $LIMIT)"
|
|
117
|
-
else
|
|
118
|
-
fail "count $COUNT drifted beyond +-15 percent of expected $EXPECTED (drift $DIFF, limit $LIMIT)"
|
|
119
|
-
echo " Review what the files[] globs now include, then refresh the fixture"
|
|
120
|
-
echo " (refresh command is in this script's header comment)."
|
|
121
|
-
fi
|
|
122
|
-
fi
|
|
123
|
-
fi
|
|
124
|
-
|
|
125
|
-
# ──────────────────────────────────────────────────────────────────────────
|
|
126
|
-
echo "→ 4. publint (optional, npx --no-install only)"
|
|
127
|
-
if (cd "$REPO_ROOT" && npx --no-install publint --help >/dev/null 2>&1); then
|
|
128
|
-
if OUT=$(cd "$REPO_ROOT" && npx --no-install publint 2>&1); then
|
|
129
|
-
pass "publint: no errors"
|
|
130
|
-
else
|
|
131
|
-
fail "publint reported errors"
|
|
132
|
-
echo "$OUT" | sed 's/^/ /'
|
|
133
|
-
fi
|
|
134
|
-
else
|
|
135
|
-
echo " ↷ SKIP: publint not installed (npx --no-install found no local package)"
|
|
136
|
-
fi
|
|
137
|
-
|
|
138
|
-
echo ""
|
|
139
|
-
echo "══ smoke-pack-contents: $PASS passed, $FAIL failed ══"
|
|
140
|
-
[ "$FAIL" -gt 0 ] && exit 1 || exit 0
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-pat-audit.sh - exercises audit-log.sh + audit-log-rotate.sh and
|
|
3
|
-
# asserts the section18.2 contract:
|
|
4
|
-
#
|
|
5
|
-
# • Every PAT lookup writes a structured event to audit.jsonl
|
|
6
|
-
# • Repo URLs are SHA-256 hashed (no plaintext)
|
|
7
|
-
# • Identity is logged by name (NOT anonymized - user's own debug)
|
|
8
|
-
# • Audit log is gitignored
|
|
9
|
-
# • Daily rotation script preserves history (gzipped) + drops >30d archives
|
|
10
|
-
|
|
11
|
-
set -uo pipefail
|
|
12
|
-
|
|
13
|
-
AUDIT_FILE="$HOME/.claude/logs/multi-agent/audit.jsonl"
|
|
14
|
-
TMP_AUDIT="$(mktemp -d -t ma-audit-smoke-XXXX)"
|
|
15
|
-
TMP_FILE="$TMP_AUDIT/audit.jsonl"
|
|
16
|
-
trap 'rm -rf "$TMP_AUDIT"' EXIT
|
|
17
|
-
|
|
18
|
-
PASS=0; FAIL=0
|
|
19
|
-
pass() { PASS=$((PASS+1)); echo " ✓ $1"; }
|
|
20
|
-
fail() { FAIL=$((FAIL+1)); echo " ✗ $1"; }
|
|
21
|
-
|
|
22
|
-
LOG="$HOME/.claude/scripts/audit-log.sh"
|
|
23
|
-
ROTATE="$HOME/.claude/scripts/audit-log-rotate.sh"
|
|
24
|
-
|
|
25
|
-
if [ ! -x "$LOG" ]; then
|
|
26
|
-
fail "audit-log.sh missing or not executable: $LOG"
|
|
27
|
-
echo "══ aborted ══"; exit 2
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
echo "→ 1. Emit a sample PAT lookup"
|
|
31
|
-
TEST_IDENTITY="smoke-user"
|
|
32
|
-
AUDIT_FILE="$TMP_FILE" "$LOG" pat_lookup bitbucket "$TEST_IDENTITY" \
|
|
33
|
-
"https://bitbucket.example.com/proj/repo" true scope=REPO_WRITE
|
|
34
|
-
[ -s "$TMP_FILE" ] && pass "audit.jsonl has content after emit" \
|
|
35
|
-
|| fail "audit.jsonl empty after emit"
|
|
36
|
-
|
|
37
|
-
LINE=$(tail -1 "$TMP_FILE")
|
|
38
|
-
echo " emitted: $LINE"
|
|
39
|
-
|
|
40
|
-
echo ""
|
|
41
|
-
echo "→ 2. Repo URL is SHA-256 hashed (not plaintext)"
|
|
42
|
-
echo "$LINE" | grep -q '"repo_url_sha":"[a-f0-9]\{64\}"' \
|
|
43
|
-
&& pass "repo_url_sha is a 64-char hex SHA-256" \
|
|
44
|
-
|| fail "repo_url_sha not in expected SHA-256 form"
|
|
45
|
-
echo "$LINE" | grep -q "bitbucket.example.com" \
|
|
46
|
-
&& fail "PLAINTEXT URL leaked into audit log!" \
|
|
47
|
-
|| pass "Plaintext URL absent (only hash present)"
|
|
48
|
-
|
|
49
|
-
echo ""
|
|
50
|
-
echo "→ 3. Identity is logged by name (per section18.2.3 - not anonymized)"
|
|
51
|
-
echo "$LINE" | grep -q "\"identity\":\"$TEST_IDENTITY\"" \
|
|
52
|
-
&& pass "identity logged as plaintext name" \
|
|
53
|
-
|| fail "identity not logged or anonymized"
|
|
54
|
-
|
|
55
|
-
echo ""
|
|
56
|
-
echo "→ 4. Service is captured"
|
|
57
|
-
echo "$LINE" | grep -q '"service":"bitbucket"' \
|
|
58
|
-
&& pass "service field captured" \
|
|
59
|
-
|| fail "service field missing"
|
|
60
|
-
|
|
61
|
-
echo ""
|
|
62
|
-
echo "→ 5. Success flag is a JSON bool (not string)"
|
|
63
|
-
echo "$LINE" | grep -q '"success":true' \
|
|
64
|
-
&& pass "success is JSON bool" \
|
|
65
|
-
|| fail "success is not bool"
|
|
66
|
-
|
|
67
|
-
echo ""
|
|
68
|
-
echo "→ 6. Extras (key=value pairs) preserved"
|
|
69
|
-
echo "$LINE" | grep -q '"scope":"REPO_WRITE"' \
|
|
70
|
-
&& pass "extras preserved (scope=REPO_WRITE)" \
|
|
71
|
-
|| fail "extras not preserved"
|
|
72
|
-
|
|
73
|
-
echo ""
|
|
74
|
-
echo "→ 7. Rotation script exists + executable"
|
|
75
|
-
[ -x "$ROTATE" ] \
|
|
76
|
-
&& pass "audit-log-rotate.sh present + executable" \
|
|
77
|
-
|| fail "audit-log-rotate.sh missing or not executable"
|
|
78
|
-
|
|
79
|
-
echo ""
|
|
80
|
-
echo "→ 8. Rotation produces a dated archive + truncates live file"
|
|
81
|
-
# Drive a dry rotation in our TMP dir
|
|
82
|
-
AUDIT_DIR="$TMP_AUDIT" bash "$ROTATE" >/dev/null 2>&1
|
|
83
|
-
ROTATED=$(find "$TMP_AUDIT" -name 'audit.*.jsonl*' -type f 2>/dev/null | head -1)
|
|
84
|
-
[ -n "$ROTATED" ] \
|
|
85
|
-
&& pass "rotation produced archive: $(basename "$ROTATED")" \
|
|
86
|
-
|| fail "rotation produced no archive"
|
|
87
|
-
[ -f "$TMP_FILE" ] && [ ! -s "$TMP_FILE" ] \
|
|
88
|
-
&& pass "live audit.jsonl truncated to empty after rotation" \
|
|
89
|
-
|| fail "live audit.jsonl not properly truncated"
|
|
90
|
-
|
|
91
|
-
echo ""
|
|
92
|
-
echo "→ 9. .gitignore covers audit logs (sensitive - never sync upstream)"
|
|
93
|
-
SMOKE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
94
|
-
GITIGNORES=(
|
|
95
|
-
"$HOME/.claude/.gitignore"
|
|
96
|
-
"$SMOKE_DIR/../../.gitignore"
|
|
97
|
-
"$HOME/multi-agent-pipeline/.gitignore"
|
|
98
|
-
)
|
|
99
|
-
GITIGNORE_OK=false
|
|
100
|
-
for gi in "${GITIGNORES[@]}"; do
|
|
101
|
-
[ -f "$gi" ] && grep -qE 'audit\.jsonl|logs/multi-agent' "$gi" 2>/dev/null && GITIGNORE_OK=true
|
|
102
|
-
done
|
|
103
|
-
$GITIGNORE_OK \
|
|
104
|
-
&& pass ".gitignore covers audit.jsonl / logs/multi-agent" \
|
|
105
|
-
|| fail ".gitignore does NOT cover audit logs (sensitive!)"
|
|
106
|
-
|
|
107
|
-
echo ""
|
|
108
|
-
echo "→ 10. Quote-bearing fields are JSON-escaped (no malformed lines)"
|
|
109
|
-
REPO_LOG="$(cd "$(dirname "$0")" && pwd)/audit-log.sh"
|
|
110
|
-
ESC_FILE="$TMP_AUDIT/escape.jsonl"
|
|
111
|
-
AUDIT_FILE="$ESC_FILE" bash "$REPO_LOG" \
|
|
112
|
-
'pat_"lookup' 'bit"bucket' 'evil" ,"injected":"x' \
|
|
113
|
-
"https://x.example/r" true 'rea"son=quote'
|
|
114
|
-
ESC_LINE=$(tail -1 "$ESC_FILE")
|
|
115
|
-
if printf '%s' "$ESC_LINE" | python3 -c 'import json,sys; json.loads(sys.stdin.read())' 2>/dev/null; then
|
|
116
|
-
pass "line with embedded double-quotes parses as valid JSON"
|
|
117
|
-
else
|
|
118
|
-
fail "embedded quotes produced malformed JSON: $ESC_LINE"
|
|
119
|
-
fi
|
|
120
|
-
if printf '%s' "$ESC_LINE" | python3 -c 'import json,sys; d=json.load(sys.stdin); sys.exit(0 if "injected" not in d else 1)' 2>/dev/null; then
|
|
121
|
-
pass "quote in field value did not inject a sibling JSON key"
|
|
122
|
-
else
|
|
123
|
-
fail "quote in field value injected an extra top-level key"
|
|
124
|
-
fi
|
|
125
|
-
|
|
126
|
-
echo ""
|
|
127
|
-
echo "══ pat-audit smoke: $PASS passed, $FAIL failed ══"
|
|
128
|
-
[ "$FAIL" -eq 0 ]
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# smoke-per-repo-memory.sh - v6.2.E
|
|
3
|
-
#
|
|
4
|
-
# Verifies the per-repo memory layer contract:
|
|
5
|
-
# 1. memory-load.sh exits silently when pref is off
|
|
6
|
-
# 2. memory-load.sh prints the wrapped block when pref is on + MEMORY.md exists
|
|
7
|
-
# 3. memory-save.sh writes the file + .gitignore + index entry
|
|
8
|
-
# 4. memory-save.sh overwrites existing slug idempotently (no duplicate index row)
|
|
9
|
-
# 5. memory-save.sh rejects invalid type + invalid slug
|
|
10
|
-
# 6. prefs schema exposes perRepoMemory toggle
|
|
11
|
-
#
|
|
12
|
-
# Exit 0 = all pass, 1 = any failure.
|
|
13
|
-
|
|
14
|
-
set -euo pipefail
|
|
15
|
-
|
|
16
|
-
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
|
17
|
-
LOAD="$ROOT/pipeline/scripts/memory-load.sh"
|
|
18
|
-
SAVE="$ROOT/pipeline/scripts/memory-save.sh"
|
|
19
|
-
SCHEMA="$ROOT/pipeline/schemas/prefs.schema.json"
|
|
20
|
-
|
|
21
|
-
pass=0
|
|
22
|
-
fail=0
|
|
23
|
-
failures=()
|
|
24
|
-
record_pass() { pass=$((pass + 1)); printf ' \033[0;32mPASS\033[0m %s\n' "$1"; }
|
|
25
|
-
record_fail() { fail=$((fail + 1)); failures+=("$1"); printf ' \033[0;31mFAIL\033[0m %s\n' "$1"; }
|
|
26
|
-
|
|
27
|
-
printf '→ smoke-per-repo-memory (v6.2.E): opt-in memory layer contract\n'
|
|
28
|
-
|
|
29
|
-
# Fresh sandbox + fake prefs
|
|
30
|
-
sandbox=$(mktemp -d)
|
|
31
|
-
mkdir -p "$sandbox/.claude"
|
|
32
|
-
HOME_SAVE="$HOME"
|
|
33
|
-
export HOME="$sandbox"
|
|
34
|
-
repo="$sandbox/repo"
|
|
35
|
-
mkdir -p "$repo"
|
|
36
|
-
|
|
37
|
-
# --- 1: pref off → silent exit 0 ---
|
|
38
|
-
printf '{"global":{"perRepoMemory":false}}' > "$HOME/.claude/multi-agent-preferences.json"
|
|
39
|
-
out=$(bash "$LOAD" "$repo" 2>&1 || true)
|
|
40
|
-
if [ -z "$out" ]; then
|
|
41
|
-
record_pass "load exits silent when pref off"
|
|
42
|
-
else
|
|
43
|
-
record_fail "load should be silent when pref off (got: $out)"
|
|
44
|
-
fi
|
|
45
|
-
|
|
46
|
-
# --- 2: pref on + no memory → silent exit 0 ---
|
|
47
|
-
printf '{"global":{"perRepoMemory":true}}' > "$HOME/.claude/multi-agent-preferences.json"
|
|
48
|
-
out=$(bash "$LOAD" "$repo" 2>&1 || true)
|
|
49
|
-
if [ -z "$out" ]; then
|
|
50
|
-
record_pass "load exits silent when pref on but no memory present"
|
|
51
|
-
else
|
|
52
|
-
record_fail "load should be silent with pref on + no memory (got: $out)"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
# --- 3: save writes file + index + gitignore ---
|
|
56
|
-
body=$(mktemp)
|
|
57
|
-
cat > "$body" <<'BODY'
|
|
58
|
-
---
|
|
59
|
-
name: audit-exhaustiveness
|
|
60
|
-
description: Audits must grep all surfaces before stating counts
|
|
61
|
-
type: feedback
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
Lead rule.
|
|
65
|
-
BODY
|
|
66
|
-
|
|
67
|
-
bash "$SAVE" "$repo" feedback audit-exhaustiveness "$body" >/dev/null
|
|
68
|
-
|
|
69
|
-
if [ -f "$repo/.multi-agent/memory/feedback_audit-exhaustiveness.md" ]; then
|
|
70
|
-
record_pass "save wrote memory file"
|
|
71
|
-
else
|
|
72
|
-
record_fail "save did not create memory file"
|
|
73
|
-
fi
|
|
74
|
-
|
|
75
|
-
if [ -f "$repo/.multi-agent/.gitignore" ]; then
|
|
76
|
-
record_pass "save created .gitignore"
|
|
77
|
-
else
|
|
78
|
-
record_fail "save did not create .gitignore"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
if grep -q 'feedback_audit-exhaustiveness.md' "$repo/.multi-agent/memory/MEMORY.md"; then
|
|
82
|
-
record_pass "save added index entry to MEMORY.md"
|
|
83
|
-
else
|
|
84
|
-
record_fail "save did not add index entry"
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
# --- 2 (second leg): pref on + memory present → emits block ---
|
|
88
|
-
out=$(bash "$LOAD" "$repo" 2>&1)
|
|
89
|
-
if grep -q '<repo-memory' <<< "$out" && grep -q 'audit-exhaustiveness' <<< "$out"; then
|
|
90
|
-
record_pass "load emits wrapped block + pointer"
|
|
91
|
-
else
|
|
92
|
-
record_fail "load should emit wrapped block with pref on + memory present"
|
|
93
|
-
fi
|
|
94
|
-
|
|
95
|
-
# --- 4: idempotent save (no duplicate index row) ---
|
|
96
|
-
cat > "$body" <<'BODY'
|
|
97
|
-
---
|
|
98
|
-
name: audit-exhaustiveness
|
|
99
|
-
description: Updated rule text (v2)
|
|
100
|
-
type: feedback
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
Updated body.
|
|
104
|
-
BODY
|
|
105
|
-
bash "$SAVE" "$repo" feedback audit-exhaustiveness "$body" >/dev/null
|
|
106
|
-
|
|
107
|
-
idx_count=$(grep -c 'feedback_audit-exhaustiveness.md' "$repo/.multi-agent/memory/MEMORY.md" || true)
|
|
108
|
-
if [ "$idx_count" = "1" ]; then
|
|
109
|
-
record_pass "idempotent save keeps index at 1 entry"
|
|
110
|
-
else
|
|
111
|
-
record_fail "idempotent save produced $idx_count entries (expected 1)"
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
if grep -q 'Updated body' "$repo/.multi-agent/memory/feedback_audit-exhaustiveness.md"; then
|
|
115
|
-
record_pass "idempotent save overwrote body"
|
|
116
|
-
else
|
|
117
|
-
record_fail "idempotent save did not update body"
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
# --- 5: invalid type / slug rejected ---
|
|
121
|
-
set +e
|
|
122
|
-
bash "$SAVE" "$repo" invalid-type bad-slug "$body" >/dev/null 2>&1
|
|
123
|
-
rc_type=$?
|
|
124
|
-
bash "$SAVE" "$repo" feedback "Bad Slug With Spaces" "$body" >/dev/null 2>&1
|
|
125
|
-
rc_slug=$?
|
|
126
|
-
set -e
|
|
127
|
-
if [ "$rc_type" != "0" ]; then
|
|
128
|
-
record_pass "save rejects invalid type"
|
|
129
|
-
else
|
|
130
|
-
record_fail "save should reject invalid type"
|
|
131
|
-
fi
|
|
132
|
-
if [ "$rc_slug" != "0" ]; then
|
|
133
|
-
record_pass "save rejects invalid slug"
|
|
134
|
-
else
|
|
135
|
-
record_fail "save should reject invalid slug"
|
|
136
|
-
fi
|
|
137
|
-
|
|
138
|
-
# --- 6: schema exposes pref ---
|
|
139
|
-
if jq -e '.properties.global.properties.perRepoMemory.default == false' "$SCHEMA" >/dev/null 2>&1; then
|
|
140
|
-
record_pass "prefs schema exposes perRepoMemory with default false"
|
|
141
|
-
else
|
|
142
|
-
record_fail "prefs schema missing perRepoMemory or wrong default"
|
|
143
|
-
fi
|
|
144
|
-
|
|
145
|
-
# cleanup
|
|
146
|
-
rm -f "$body"
|
|
147
|
-
rm -rf "$sandbox"
|
|
148
|
-
export HOME="$HOME_SAVE"
|
|
149
|
-
|
|
150
|
-
printf '\n══ per-repo-memory smoke: %d passed, %d failed ══\n' "$pass" "$fail"
|
|
151
|
-
if [ "$fail" -gt 0 ]; then
|
|
152
|
-
printf '\nFailures:\n'
|
|
153
|
-
for msg in "${failures[@]}"; do printf ' - %s\n' "$msg"; done
|
|
154
|
-
exit 1
|
|
155
|
-
fi
|
|
156
|
-
exit 0
|