mandrel 1.94.0 → 2.1.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/.agents/README.md +116 -99
- package/.agents/agents/acceptance-critic.md +9 -7
- package/.agents/agents/story-worker.md +45 -51
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +498 -1287
- package/.agents/docs/agentrc-reference.json +185 -80
- package/.agents/docs/configuration.md +132 -190
- package/.agents/docs/execution-reference.md +51 -25
- package/.agents/docs/quality-gates.md +25 -33
- package/.agents/docs/workflows.md +8 -8
- package/.agents/instructions.md +113 -139
- package/.agents/rules/ci-remediation.md +11 -15
- package/.agents/rules/git-conventions-reference.md +48 -58
- package/.agents/rules/git-conventions.md +16 -22
- package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
- package/.agents/schemas/agentrc.schema.json +83 -254
- package/.agents/schemas/audit-rules.json +59 -1
- package/.agents/schemas/audit-rules.schema.json +33 -1
- package/.agents/schemas/lifecycle/README.md +1 -2
- package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
- package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
- package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
- package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
- package/.agents/schemas/signal-event.schema.json +3 -3
- package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
- package/.agents/schemas/validation-evidence.schema.json +1 -1
- package/.agents/scripts/acceptance-eval.js +22 -66
- package/.agents/scripts/agents-bootstrap-github.js +1 -1
- package/.agents/scripts/audit-to-stories.js +7 -7
- package/.agents/scripts/boot-sweep.js +1 -1
- package/.agents/scripts/bootstrap.js +3 -3
- package/.agents/scripts/check-dead-exports.js +43 -104
- package/.agents/scripts/check-doc-links.js +2 -2
- package/.agents/scripts/check-lifecycle-lint.js +7 -10
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
- package/.agents/scripts/deliver-recover.js +122 -0
- package/.agents/scripts/drain-pending-cleanup.js +1 -1
- package/.agents/scripts/evidence-gate.js +20 -50
- package/.agents/scripts/generate-skills-index.js +17 -1
- package/.agents/scripts/generate-workflows-doc.js +4 -4
- package/.agents/scripts/lib/ITicketingProvider.js +1 -19
- package/.agents/scripts/lib/Logger.js +6 -10
- package/.agents/scripts/lib/audit-suite/runner.js +2 -2
- package/.agents/scripts/lib/audit-suite/selector.js +328 -28
- package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
- package/.agents/scripts/lib/baselines/kernel.js +206 -18
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
- package/.agents/scripts/lib/baselines/reader.js +1 -6
- package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
- package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
- package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
- package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
- package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
- package/.agents/scripts/lib/checks/index.js +3 -2
- package/.agents/scripts/lib/checks/loop-health.js +12 -11
- package/.agents/scripts/lib/checks/state.js +17 -248
- package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
- package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
- package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
- package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
- package/.agents/scripts/lib/cli/standard-args.js +13 -22
- package/.agents/scripts/lib/cli-args.js +39 -9
- package/.agents/scripts/lib/close-validation/gates.js +15 -15
- package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
- package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
- package/.agents/scripts/lib/close-validation/runner.js +13 -21
- package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
- package/.agents/scripts/lib/config/ci.js +6 -31
- package/.agents/scripts/lib/config/delivery-routing.js +52 -35
- package/.agents/scripts/lib/config/explain.js +61 -48
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +29 -80
- package/.agents/scripts/lib/config/paths.js +0 -2
- package/.agents/scripts/lib/config/quality.js +12 -15
- package/.agents/scripts/lib/config/runners.js +20 -66
- package/.agents/scripts/lib/config/temp-paths.js +30 -63
- package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
- package/.agents/scripts/lib/config-resolver.js +2 -7
- package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
- package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
- package/.agents/scripts/lib/config-settings-schema.js +100 -60
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/dependency-parser.js +3 -2
- package/.agents/scripts/lib/doc-tiers.js +2 -2
- package/.agents/scripts/lib/duplicate-search.js +242 -41
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/findings/promote-finding.js +23 -14
- package/.agents/scripts/lib/format-generated-json.js +97 -0
- package/.agents/scripts/lib/framework-version.js +19 -190
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
- package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
- package/.agents/scripts/lib/git-utils.js +32 -20
- package/.agents/scripts/lib/github/framework-repo.js +6 -0
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +10 -38
- package/.agents/scripts/lib/label-taxonomy.js +10 -55
- package/.agents/scripts/lib/observability/active-story-env.js +44 -165
- package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
- package/.agents/scripts/lib/observability/signal-validator.js +4 -4
- package/.agents/scripts/lib/observability/signals-writer.js +6 -82
- package/.agents/scripts/lib/observability/source-classifier.js +5 -5
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- package/.agents/scripts/lib/onboard/init-tail.js +1 -3
- package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
- package/.agents/scripts/lib/orchestration/code-review.js +78 -436
- package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
- package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
- package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
- package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
- package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
- package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
- package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
- package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
- package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
- package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
- package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
- package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
- package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
- package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
- package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
- package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
- package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
- package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
- package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
- package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
- package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
- package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
- package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
- package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
- package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
- package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
- package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
- package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
- package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
- package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
- package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
- package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
- package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
- package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
- package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
- package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
- package/.agents/scripts/lib/planning-corpus.js +12 -281
- package/.agents/scripts/lib/preflight-runner.js +4 -4
- package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
- package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
- package/.agents/scripts/lib/signals/index.js +4 -17
- package/.agents/scripts/lib/signals/read.js +35 -35
- package/.agents/scripts/lib/signals/schema.js +8 -11
- package/.agents/scripts/lib/signals/span-tree.js +7 -7
- package/.agents/scripts/lib/signals/write.js +0 -1
- package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
- package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
- package/.agents/scripts/lib/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +17 -19
- package/.agents/scripts/lib/story-body/story-body.js +130 -75
- package/.agents/scripts/lib/story-plan.js +2 -4
- package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
- package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
- package/.agents/scripts/lib/validation-evidence.js +32 -60
- package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
- package/.agents/scripts/lib/workspace-provisioner.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/lint-issue-body.js +71 -40
- package/.agents/scripts/mandrel-update-preflight.js +1 -1
- package/.agents/scripts/notify.js +4 -3
- package/.agents/scripts/plan-context.js +102 -80
- package/.agents/scripts/plan-persist.js +230 -279
- package/.agents/scripts/plan-run-epilogue.js +142 -0
- package/.agents/scripts/post-structured-comment.js +0 -38
- package/.agents/scripts/pr-watch-with-update.js +43 -22
- package/.agents/scripts/providers/github/compose.js +0 -1
- package/.agents/scripts/providers/github/errors.js +0 -19
- package/.agents/scripts/providers/github/issues.js +13 -39
- package/.agents/scripts/providers/github/mappers.js +5 -12
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -156
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/resolve-stories.js +236 -0
- package/.agents/scripts/run-coverage.js +4 -1
- package/.agents/scripts/run-lint.js +2 -2
- package/.agents/scripts/run-verify.js +31 -2
- package/.agents/scripts/signals-view.js +25 -21
- package/.agents/scripts/single-story-close.js +178 -26
- package/.agents/scripts/single-story-confirm-merge.js +313 -24
- package/.agents/scripts/single-story-init.js +35 -30
- package/.agents/scripts/stories-wave-tick.js +85 -10
- package/.agents/scripts/story-plan.js +28 -49
- package/.agents/scripts/update-ticket-state.js +14 -65
- package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
- package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
- package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
- package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
- package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
- package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
- package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
- package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
- package/.agents/skills/core/scope-triage/SKILL.md +31 -172
- package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
- package/.agents/skills/core/security-and-hardening/reference.md +375 -0
- package/.agents/skills/skills.index.json +3 -53
- package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
- package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
- package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
- package/.agents/starter-agentrc.json +0 -5
- package/.agents/templates/agent-protocol.md +9 -10
- package/.agents/workflows/audit-architecture.md +6 -7
- package/.agents/workflows/audit-clean-code.md +7 -7
- package/.agents/workflows/audit-dependencies.md +3 -3
- package/.agents/workflows/audit-devops.md +3 -3
- package/.agents/workflows/audit-documentation.md +9 -10
- package/.agents/workflows/audit-lighthouse.md +11 -3
- package/.agents/workflows/audit-navigability.md +13 -2
- package/.agents/workflows/audit-performance.md +5 -6
- package/.agents/workflows/audit-privacy.md +3 -3
- package/.agents/workflows/audit-quality.md +11 -12
- package/.agents/workflows/audit-security.md +4 -5
- package/.agents/workflows/audit-seo.md +13 -3
- package/.agents/workflows/audit-sre.md +3 -3
- package/.agents/workflows/audit-to-stories.md +20 -20
- package/.agents/workflows/audit-ux-ui.md +10 -3
- package/.agents/workflows/deliver.md +177 -176
- package/.agents/workflows/git-cleanup.md +5 -6
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
- package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
- package/.agents/workflows/helpers/code-review.md +75 -196
- package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
- package/.agents/workflows/helpers/deliver-story.md +606 -0
- package/.agents/workflows/helpers/diagnose.md +10 -10
- package/.agents/workflows/helpers/parallel-tooling.md +3 -3
- package/.agents/workflows/helpers/signals.md +16 -16
- package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
- package/.agents/workflows/mandrel-update.md +2 -1
- package/.agents/workflows/plan.md +277 -145
- package/.agents/workflows/qa-assist.md +27 -33
- package/.agents/workflows/qa-explore.md +29 -38
- package/.agents/workflows/qa-run.md +2 -6
- package/README.md +9 -8
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +70 -0
- package/lib/cli/registry.js +262 -19
- package/lib/cli/sync-agents.js +157 -0
- package/lib/cli/sync-commands.js +115 -6
- package/lib/cli/sync.js +168 -6
- package/lib/cli/update.js +105 -8
- package/lib/cli/version-helpers.js +131 -0
- package/lib/migrations/README.md +7 -5
- package/lib/migrations/index.js +12 -8
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
- package/package.json +2 -2
- package/.agents/agents/retro.md +0 -42
- package/.agents/personas/architect.md +0 -113
- package/.agents/personas/devops-engineer.md +0 -38
- package/.agents/personas/engineer.md +0 -33
- package/.agents/personas/project-manager.md +0 -114
- package/.agents/personas/qa-engineer.md +0 -95
- package/.agents/personas/security-engineer.md +0 -111
- package/.agents/personas/technical-writer.md +0 -101
- package/.agents/schemas/dispatch-manifest.json +0 -232
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- package/.agents/schemas/epic-spec.schema.json +0 -153
- package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
- package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
- package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
- package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
- package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
- package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
- package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
- package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
- package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
- package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
- package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
- package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
- package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
- package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -66
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/bookkeeping-reconcile.js +0 -117
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- package/.agents/scripts/dispatcher.js +0 -295
- package/.agents/scripts/epic-audit-prepare.js +0 -497
- package/.agents/scripts/epic-audit-recheck.js +0 -274
- package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
- package/.agents/scripts/epic-deliver-preflight.js +0 -462
- package/.agents/scripts/epic-deliver-prepare.js +0 -852
- package/.agents/scripts/epic-execute-record-wave.js +0 -449
- package/.agents/scripts/epic-plan-clarity.js +0 -211
- package/.agents/scripts/epic-plan-healthcheck.js +0 -581
- package/.agents/scripts/epic-reconcile.js +0 -625
- package/.agents/scripts/lib/baseline-snapshot.js +0 -979
- package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
- package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
- package/.agents/scripts/lib/config/lifecycle.js +0 -40
- package/.agents/scripts/lib/config/preflight.js +0 -58
- package/.agents/scripts/lib/config/retro.js +0 -77
- package/.agents/scripts/lib/epic-merge-lock.js +0 -322
- package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
- package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
- package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
- package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
- package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
- package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
- package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
- package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
- package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
- package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
- package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
- package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
- package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
- package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
- package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
- package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
- package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
- package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
- package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
- package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
- package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
- package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
- package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
- package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
- package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
- package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
- package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
- package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
- package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
- package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
- package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
- package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
- package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
- package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
- package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
- package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
- package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
- package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
- package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
- package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
- package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
- package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
- package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
- package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
- package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
- package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
- package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
- package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
- package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
- package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
- package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
- package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
- package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
- package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
- package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
- package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
- package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
- package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
- package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
- package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
- package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
- package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
- package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
- package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
- package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
- package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
- package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
- package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
- package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
- package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
- package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
- package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
- package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
- package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
- package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
- package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
- package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
- package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
- package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
- package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
- package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
- package/.agents/scripts/lib/push-epic-retry.js +0 -209
- package/.agents/scripts/lib/spec/index.js +0 -36
- package/.agents/scripts/lib/spec/loader.js +0 -425
- package/.agents/scripts/lib/spec/state.js +0 -208
- package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
- package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
- package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
- package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
- package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
- package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
- package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
- package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
- package/.agents/scripts/lib/wave-runner/tick.js +0 -754
- package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
- package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
- package/.agents/scripts/lifecycle-emit.js +0 -510
- package/.agents/scripts/retro-run.js +0 -218
- package/.agents/scripts/slice-phase.js +0 -361
- package/.agents/scripts/standalone-feedback-rollup.js +0 -188
- package/.agents/scripts/story-close.js +0 -294
- package/.agents/scripts/story-init.js +0 -599
- package/.agents/scripts/story-phase.js +0 -369
- package/.agents/scripts/wave-tick.js +0 -464
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
- package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
- package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
- package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
- package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
- package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
- package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
- package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
- package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
- package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
- package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
- package/.agents/workflows/helpers/deliver-epic.md +0 -998
- package/.agents/workflows/helpers/deliver-stories.md +0 -450
- package/.agents/workflows/helpers/epic-audit.md +0 -189
- package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
- package/.agents/workflows/helpers/epic-testing.md +0 -125
- package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
- package/.agents/workflows/helpers/plan-epic.md +0 -353
- package/.agents/workflows/helpers/plan-story.md +0 -251
- package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
- package/.agents/workflows/helpers/single-story-deliver.md +0 -557
|
@@ -1,189 +1,48 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: scope-triage
|
|
3
3
|
description:
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
planning gate that needs the canonical story-vs-epic rubric.
|
|
4
|
+
Optional split-advisory for `/plan`. Under v2 there is no epic|story routing
|
|
5
|
+
verdict — `/plan` always authors Stories. Use this skill only when judging
|
|
6
|
+
whether a draft should stay one Story or legitimately split (near-zero
|
|
7
|
+
overlap or an architectural seam).
|
|
9
8
|
---
|
|
10
9
|
|
|
11
|
-
# scope-triage
|
|
10
|
+
# scope-triage (split advisory)
|
|
12
11
|
|
|
13
12
|
## Policy Capsule
|
|
14
13
|
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
- There is **no** `epic | story | borderline` routing verdict in v2. `/plan`
|
|
15
|
+
is a single path that emits **one Story by default**.
|
|
16
|
+
- This skill is an optional **split advisory**: should the author keep one
|
|
17
|
+
Story, or does the seed clear the default-single split policy?
|
|
18
|
+
- Anchor sizing judgment to `DEFAULT_MODEL_CAPACITY` and
|
|
19
|
+
`DELIVERABLE_GRANULARITY_GUIDANCE` in
|
|
20
20
|
[`ticket-validator-sizing.js`](../../../scripts/lib/orchestration/ticket-validator-sizing.js).
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
with: one Story is *one coherent change with one reason to exist*. The file /
|
|
29
|
-
acceptance ceilings are the backstop, not the first cut.
|
|
30
|
-
- Bias toward `epic` only when the work genuinely spans multiple independent
|
|
31
|
-
capabilities, crosses subsystems, or carries a real dependency graph. Being
|
|
32
|
-
wrong in the `epic` direction is cheap — the Phase 8.3 consolidation pass and
|
|
33
|
-
the sizing validator catch an over-planned Story later. Being wrong in the
|
|
34
|
-
`story` direction is expensive — a story-sized scope pushed through the full
|
|
35
|
-
Epic ceremony pays a sectioned-Epic-body (Tech Spec + Acceptance Table) +
|
|
36
|
-
Story backlog +
|
|
37
|
-
`epic/<id>` integration-branch tax for a degenerate one-Story output.
|
|
38
|
-
- Keep the rubric prose **artifact-agnostic**. The thing under judgment may be a
|
|
39
|
-
sharpened one-pager, an existing Epic body, or a draft Story — the rubric
|
|
40
|
-
reads the same against all three so every consumer reuses it verbatim.
|
|
21
|
+
Do not restate numeric thresholds.
|
|
22
|
+
- Lead with **cohesion**: one Story is one coherent change with one reason
|
|
23
|
+
to exist. Coupled work stays one Story and uses `## Slicing` for
|
|
24
|
+
intra-session checkpoints.
|
|
25
|
+
- Emit an **advisory only** — `keep-single` (the default) or `split` with its
|
|
26
|
+
seam/overlap rationale. **Never auto-route**: the operator decides, and
|
|
27
|
+
`--yes` defaults to `keep-single`.
|
|
41
28
|
|
|
42
|
-
##
|
|
29
|
+
## Split policy (when N>1 is allowed)
|
|
43
30
|
|
|
44
|
-
|
|
31
|
+
Split into sibling Stories **only** when:
|
|
45
32
|
|
|
46
|
-
|
|
33
|
+
1. **Near-zero overlap** — genuinely independent capabilities that happen to
|
|
34
|
+
share a seed idea, or
|
|
35
|
+
2. **Architectural seam** — different deployables, or a migration vs the
|
|
36
|
+
feature that consumes it.
|
|
47
37
|
|
|
48
|
-
|
|
38
|
+
Otherwise keep one Story. Persist refuses coupled splits via
|
|
39
|
+
`assertAcceptancePartition` (identical AC text across Stories).
|
|
49
40
|
|
|
50
|
-
|
|
51
|
-
change a reviewer would accept as a single PR — the
|
|
52
|
-
`DELIVERABLE_GRANULARITY_GUIDANCE.definition` notion of a Story.
|
|
53
|
-
- **Acceptance fits one Story.** The acceptance-criteria list reads as the
|
|
54
|
-
binding contract of one coherent capability rather than spanning many
|
|
55
|
-
independent outcomes. Acceptance mass is advisory-only (the
|
|
56
|
-
`softAcceptanceCount` nudge in `DEFAULT_TASK_SIZING` — there is no hard
|
|
57
|
-
ceiling), so the question is cohesion, not count.
|
|
58
|
-
- **Footprint fits Story sizing.** The plausible file footprint fits the Story
|
|
59
|
-
width described by `DEFAULT_TASK_SIZING` (the `softFiles` / `hardFiles`
|
|
60
|
-
knobs); a legitimately broad-but-cohesive change would declare `wide` rather
|
|
61
|
-
than being two Stories.
|
|
62
|
-
- **No novel architecture, no high-risk trigger.** The work introduces no novel
|
|
63
|
-
architectural decision and matches none of the `planning.riskHeuristics` in
|
|
64
|
-
`.agentrc.json` (destructive/irreversible changes, shared auth/security,
|
|
65
|
-
CI/CD gate changes, monorepo-wide rewrites, destructive migrations).
|
|
66
|
-
- **Decomposition would degenerate.** Running it through `/plan` would
|
|
67
|
-
plausibly yield exactly **one Feature with one Story** — the shape the Phase
|
|
68
|
-
8.3 consolidation skill flags only after all the spec authoring is already
|
|
69
|
-
sunk cost.
|
|
41
|
+
## Advisory output
|
|
70
42
|
|
|
71
|
-
|
|
43
|
+
Emit one of:
|
|
72
44
|
|
|
73
|
-
|
|
45
|
+
- `keep-single` — default; fold complexity into `## Spec` / `## Slicing`
|
|
46
|
+
- `split` — list the proposed Stories and the seam/overlap rationale
|
|
74
47
|
|
|
75
|
-
-
|
|
76
|
-
capabilities that each stand alone as a unit of work.
|
|
77
|
-
- **Cross-subsystem blast radius.** The change reaches across subsystems that
|
|
78
|
-
do not share one cohesive reason to exist.
|
|
79
|
-
- **A real dependency graph.** The work has internal ordering — slices that
|
|
80
|
-
must land before others — rather than one atomic change.
|
|
81
|
-
|
|
82
|
-
### `borderline`
|
|
83
|
-
|
|
84
|
-
The work is genuinely on the line — it could reasonably be one ambitious Story
|
|
85
|
-
or a small Epic, and neither call is clearly right. **Present the choice rather
|
|
86
|
-
than deciding for the operator.** Do not force a verdict to avoid the third
|
|
87
|
-
option; a borderline scope surfaced as borderline is the correct output.
|
|
88
|
-
|
|
89
|
-
## Change-Request Triage Rubric
|
|
90
|
-
|
|
91
|
-
A **change request** — "fix this", "tweak that", "extend the existing X" —
|
|
92
|
-
is the common case this rubric routes cheaply: a delta against a surface the
|
|
93
|
-
project already shipped, not a from-scratch capability. Route it to `story`
|
|
94
|
-
by default when all three delta signals hold; treat any one signal's absence
|
|
95
|
-
as a prompt to re-check, not an automatic `epic` bump.
|
|
96
|
-
|
|
97
|
-
### Delta signals
|
|
98
|
-
|
|
99
|
-
- **Delta to an already-delivered surface.** The request references a
|
|
100
|
-
concrete existing capability (a module, workflow, script, or shipped
|
|
101
|
-
feature) rather than proposing a new one. "Fix the flaky retry in
|
|
102
|
-
`evidence-gate.js`" is a delta; "add a retry framework" is not.
|
|
103
|
-
- **Existing corpus covers the touched area.** The project's docs digest
|
|
104
|
-
and/or an already-closed or in-flight Epic's Tech Spec section already
|
|
105
|
-
describe the surface being changed — the standalone-Story path can draft
|
|
106
|
-
against that inherited context (`corpusContext` in the `/plan --idea`
|
|
107
|
-
envelope) instead of re-deriving architecture from a blank slate. When no
|
|
108
|
-
corpus hit exists for the touched area, that is a signal the request may
|
|
109
|
-
be reaching into genuinely new territory — re-check the `epic` signals
|
|
110
|
-
below before defaulting to `story`.
|
|
111
|
-
- **Footprint fits Story sizing.** The plausible file footprint and
|
|
112
|
-
acceptance-criteria count still fit the Story width in
|
|
113
|
-
`DEFAULT_TASK_SIZING` (per the `story` verdict signals above) — a change
|
|
114
|
-
request that fans out across independent subsystems is sized like an Epic
|
|
115
|
-
regardless of how small the originating request sounded.
|
|
116
|
-
|
|
117
|
-
### Story-verdict rationale template
|
|
118
|
-
|
|
119
|
-
Use this template to record the verdict — it names which delta signal
|
|
120
|
-
carried the call, so a reviewer can sanity-check the routing decision without
|
|
121
|
-
re-deriving it:
|
|
122
|
-
|
|
123
|
-
```text
|
|
124
|
-
Verdict: story
|
|
125
|
-
Delta: <the existing surface this change targets>
|
|
126
|
-
Corpus hit: <docs digest section / Epic # and Tech Spec excerpt that covers
|
|
127
|
-
this area, or "none — re-checked epic signals, still story-sized">
|
|
128
|
-
Footprint: <rough file/AC count vs DEFAULT_TASK_SIZING>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Worked example
|
|
132
|
-
|
|
133
|
-
> Request: "The `/plan` standalone-Story path always drafts from a blank
|
|
134
|
-
> slate even when a change request is a small delta against something we
|
|
135
|
-
> already shipped — thread the existing docs digest and matching Epic
|
|
136
|
-
> Tech Spec sections into the draft context."
|
|
137
|
-
>
|
|
138
|
-
> ```text
|
|
139
|
-
> Verdict: story
|
|
140
|
-
> Delta: story-plan.js's --emit-context envelope and the plan-story.md
|
|
141
|
-
> Phase 2 drafting instructions — both already exist and ship today.
|
|
142
|
-
> Corpus hit: Epic #4429's own Tech Spec section (this rubric's parent
|
|
143
|
-
> Epic) already describes the docs-digest reuse pattern from
|
|
144
|
-
> orchestration/docs-digest.js.
|
|
145
|
-
> Footprint: one new lib module (planning-corpus.js), one envelope field,
|
|
146
|
-
> one helper-doc instruction — comfortably inside DEFAULT_TASK_SIZING's
|
|
147
|
-
> softFiles/softAcceptanceCount band.
|
|
148
|
-
> ```
|
|
149
|
-
|
|
150
|
-
## Handoff & no-re-triage rule
|
|
151
|
-
|
|
152
|
-
A workflow entered via a scope-triage **handoff** MUST NOT re-triage. A handoff
|
|
153
|
-
*is* a triage decision already made — re-running this gate on the receiving side
|
|
154
|
-
would re-litigate a settled call and risk a ping-pong between two planning
|
|
155
|
-
workflows. Handoff invocations identify themselves as such (e.g. `/plan`
|
|
156
|
-
entered via a `/plan` scope-triage escalation, or `/plan` entered
|
|
157
|
-
via an `/plan` Phase 1.5 handoff), and the receiving workflow skips its own
|
|
158
|
-
scope-triage gate when it detects the handoff marker.
|
|
159
|
-
|
|
160
|
-
## When to use
|
|
161
|
-
|
|
162
|
-
- **`/plan` Phase 1.5** (ideation path only) — judge the sharpened
|
|
163
|
-
one-pager Phase 1 produced before the Epic ceremony is paid for. The verdict
|
|
164
|
-
folds into the existing Phase 1 HITL stop; on a `story` / `borderline`
|
|
165
|
-
verdict the operator may hand off to
|
|
166
|
-
[`/plan --from-notes`](../../../workflows/helpers/plan-story.md).
|
|
167
|
-
- Any other planning gate that needs the canonical story-vs-epic rubric. Keep
|
|
168
|
-
the rubric here as the SSOT; consumers reference this file rather than
|
|
169
|
-
forking the prose.
|
|
170
|
-
|
|
171
|
-
## Output
|
|
172
|
-
|
|
173
|
-
A single verdict (`epic` | `story` | `borderline`) plus a one-paragraph
|
|
174
|
-
rationale grounded in the signals above. The rationale names the deciding
|
|
175
|
-
signal (cohesion, capability count, blast radius, dependency graph, or sizing
|
|
176
|
-
fit) so the operator can sanity-check the call before acting on it.
|
|
177
|
-
|
|
178
|
-
## Anti-patterns to avoid
|
|
179
|
-
|
|
180
|
-
- **Restating the sizing numbers.** Reference `DEFAULT_TASK_SIZING` /
|
|
181
|
-
`DELIVERABLE_GRANULARITY_GUIDANCE`; never copy the thresholds into this file
|
|
182
|
-
(they would drift from the validator).
|
|
183
|
-
- **Auto-routing on the verdict.** The verdict is advisory; the operator
|
|
184
|
-
decides. Never silently fork a workflow on a `story` verdict.
|
|
185
|
-
- **Forcing a binary call.** When the work is genuinely on the line, emit
|
|
186
|
-
`borderline` and present the choice. Do not collapse it to `epic` or `story`
|
|
187
|
-
to look decisive.
|
|
188
|
-
- **Re-triaging after a handoff.** A handoff is a settled decision. Skip the
|
|
189
|
-
gate when the invocation identifies itself as a scope-triage handoff.
|
|
48
|
+
Never auto-route. The operator (or `--yes` default = `keep-single`) decides.
|
|
@@ -31,370 +31,25 @@ patterns and process guidance; read the rule for the **what**. When the rule
|
|
|
31
31
|
and this skill diverge, the rule wins — open a PR against the rule rather
|
|
32
32
|
than working around it here.
|
|
33
33
|
|
|
34
|
-
##
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
- Granting elevated permissions or roles
|
|
57
|
-
|
|
58
|
-
For each item that applies, call it out under a "Security surface" section
|
|
59
|
-
in the PR body and on the parent ticket, label the change `risk::high`,
|
|
60
|
-
and link the relevant `security-baseline.md` MUST. Reviewers gate the
|
|
61
|
-
merge; the agent keeps moving.
|
|
62
|
-
|
|
63
|
-
`agent::blocked` remains the **only** runtime pause label. Use it for
|
|
64
|
-
unrecoverable blockers (missing prerequisite, ambiguous spec a sub-agent
|
|
65
|
-
cannot resolve), not for "this change is sensitive." Sensitive changes
|
|
66
|
-
ship through the documentation path above.
|
|
67
|
-
|
|
68
|
-
## OWASP Top 10 Prevention Patterns
|
|
69
|
-
|
|
70
|
-
The patterns below show **how** to satisfy the MUSTs in
|
|
71
|
-
[`security-baseline.md`](../../../rules/security-baseline.md). The MUSTs
|
|
72
|
-
themselves (parameterize queries, hash passwords, encode output, verify
|
|
73
|
-
ownership, set headers, restrict CORS, exclude sensitive fields) are listed
|
|
74
|
-
in the rule.
|
|
75
|
-
|
|
76
|
-
### 1. Injection (SQL, NoSQL, OS Command)
|
|
77
|
-
|
|
78
|
-
See [security-baseline § Output & Rendering](../../../rules/security-baseline.md#output--rendering).
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
// BAD: SQL injection via string concatenation
|
|
82
|
-
const query = `SELECT * FROM users WHERE id = '${userId}'`;
|
|
83
|
-
|
|
84
|
-
// GOOD: Parameterized query
|
|
85
|
-
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
|
|
86
|
-
|
|
87
|
-
// GOOD: ORM with parameterized input
|
|
88
|
-
const user = await prisma.user.findUnique({ where: { id: userId } });
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### 2. Broken Authentication
|
|
92
|
-
|
|
93
|
-
See [security-baseline § Authentication](../../../rules/security-baseline.md#authentication).
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
import { hash, compare } from 'bcrypt';
|
|
97
|
-
|
|
98
|
-
const SALT_ROUNDS = 12;
|
|
99
|
-
const hashedPassword = await hash(plaintext, SALT_ROUNDS);
|
|
100
|
-
const isValid = await compare(plaintext, hashedPassword);
|
|
101
|
-
|
|
102
|
-
// Session management
|
|
103
|
-
app.use(
|
|
104
|
-
session({
|
|
105
|
-
secret: process.env.SESSION_SECRET, // From environment, not code
|
|
106
|
-
resave: false,
|
|
107
|
-
saveUninitialized: false,
|
|
108
|
-
cookie: {
|
|
109
|
-
httpOnly: true,
|
|
110
|
-
secure: true,
|
|
111
|
-
sameSite: 'lax',
|
|
112
|
-
maxAge: 24 * 60 * 60 * 1000,
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### 3. Cross-Site Scripting (XSS)
|
|
119
|
-
|
|
120
|
-
See [security-baseline § Output & Rendering](../../../rules/security-baseline.md#output--rendering).
|
|
121
|
-
|
|
122
|
-
```typescript
|
|
123
|
-
// BAD: Rendering user input as HTML
|
|
124
|
-
element.innerHTML = userInput;
|
|
125
|
-
|
|
126
|
-
// GOOD: Use framework auto-escaping (React does this by default)
|
|
127
|
-
return <div>{userInput}</div>;
|
|
128
|
-
|
|
129
|
-
// If you MUST render HTML, sanitize first
|
|
130
|
-
import DOMPurify from 'dompurify';
|
|
131
|
-
const clean = DOMPurify.sanitize(userInput);
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### 4. Broken Access Control
|
|
135
|
-
|
|
136
|
-
See [security-baseline § Authorization](../../../rules/security-baseline.md#authorization).
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
app.patch('/api/tasks/:id', authenticate, async (req, res) => {
|
|
140
|
-
const task = await taskService.findById(req.params.id);
|
|
141
|
-
|
|
142
|
-
if (task.ownerId !== req.user.id) {
|
|
143
|
-
return res.status(403).json({
|
|
144
|
-
error: {
|
|
145
|
-
code: 'FORBIDDEN',
|
|
146
|
-
message: 'Not authorized to modify this task',
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const updated = await taskService.update(req.params.id, req.body);
|
|
152
|
-
return res.json(updated);
|
|
153
|
-
});
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### 5. Security Misconfiguration
|
|
157
|
-
|
|
158
|
-
See [security-baseline § Transport & Headers](../../../rules/security-baseline.md#transport--headers).
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
import helmet from 'helmet';
|
|
162
|
-
app.use(helmet());
|
|
163
|
-
|
|
164
|
-
app.use(
|
|
165
|
-
helmet.contentSecurityPolicy({
|
|
166
|
-
directives: {
|
|
167
|
-
defaultSrc: ["'self'"],
|
|
168
|
-
scriptSrc: ["'self'"],
|
|
169
|
-
styleSrc: ["'self'", "'unsafe-inline'"],
|
|
170
|
-
imgSrc: ["'self'", 'data:', 'https:'],
|
|
171
|
-
connectSrc: ["'self'"],
|
|
172
|
-
},
|
|
173
|
-
}),
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
app.use(
|
|
177
|
-
cors({
|
|
178
|
-
origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
|
|
179
|
-
credentials: true,
|
|
180
|
-
}),
|
|
181
|
-
);
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### 6. Sensitive Data Exposure
|
|
185
|
-
|
|
186
|
-
See [security-baseline § Output & Rendering](../../../rules/security-baseline.md#output--rendering)
|
|
187
|
-
and [§ Secrets Management](../../../rules/security-baseline.md#secrets-management).
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
function sanitizeUser(user: UserRecord): PublicUser {
|
|
191
|
-
const { passwordHash, resetToken, ...publicFields } = user;
|
|
192
|
-
return publicFields;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const API_KEY = process.env.STRIPE_API_KEY;
|
|
196
|
-
if (!API_KEY) throw new Error('STRIPE_API_KEY not configured');
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## Input Validation Patterns
|
|
200
|
-
|
|
201
|
-
See [security-baseline § Input Validation](../../../rules/security-baseline.md#input-validation).
|
|
202
|
-
|
|
203
|
-
### Schema Validation at Boundaries
|
|
204
|
-
|
|
205
|
-
```typescript
|
|
206
|
-
import { z } from 'zod';
|
|
207
|
-
|
|
208
|
-
const CreateTaskSchema = z.object({
|
|
209
|
-
title: z.string().min(1).max(200).trim(),
|
|
210
|
-
description: z.string().max(2000).optional(),
|
|
211
|
-
priority: z.enum(['low', 'medium', 'high']).default('medium'),
|
|
212
|
-
dueDate: z.string().datetime().optional(),
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
app.post('/api/tasks', async (req, res) => {
|
|
216
|
-
const result = CreateTaskSchema.safeParse(req.body);
|
|
217
|
-
if (!result.success) {
|
|
218
|
-
return res.status(422).json({
|
|
219
|
-
error: {
|
|
220
|
-
code: 'VALIDATION_ERROR',
|
|
221
|
-
message: 'Invalid input',
|
|
222
|
-
details: result.error.flatten(),
|
|
223
|
-
},
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
const task = await taskService.create(result.data);
|
|
227
|
-
return res.status(201).json(task);
|
|
228
|
-
});
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
### File Upload Safety
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp'];
|
|
235
|
-
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
|
|
236
|
-
|
|
237
|
-
function validateUpload(file: UploadedFile) {
|
|
238
|
-
if (!ALLOWED_TYPES.includes(file.mimetype)) {
|
|
239
|
-
throw new ValidationError('File type not allowed');
|
|
240
|
-
}
|
|
241
|
-
if (file.size > MAX_SIZE) {
|
|
242
|
-
throw new ValidationError('File too large (max 5MB)');
|
|
243
|
-
}
|
|
244
|
-
// Don't trust the file extension — check magic bytes if critical
|
|
245
|
-
}
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
## Triaging npm audit Results
|
|
249
|
-
|
|
250
|
-
The MUST is in [security-baseline § Dependency Hygiene](../../../rules/security-baseline.md#dependency-hygiene).
|
|
251
|
-
This decision tree shows how to prioritize:
|
|
252
|
-
|
|
253
|
-
```text
|
|
254
|
-
npm audit reports a vulnerability
|
|
255
|
-
├── Severity: critical or high
|
|
256
|
-
│ ├── Is the vulnerable code reachable in your app?
|
|
257
|
-
│ │ ├── YES --> Fix immediately (update, patch, or replace the dependency)
|
|
258
|
-
│ │ └── NO (dev-only dep, unused code path) --> Fix soon, but not a blocker
|
|
259
|
-
│ └── Is a fix available?
|
|
260
|
-
│ ├── YES --> Update to the patched version
|
|
261
|
-
│ └── NO --> Check for workarounds, consider replacing the dependency, or add to allowlist with a review date
|
|
262
|
-
├── Severity: moderate
|
|
263
|
-
│ ├── Reachable in production? --> Fix in the next release cycle
|
|
264
|
-
│ └── Dev-only? --> Fix when convenient, track in backlog
|
|
265
|
-
└── Severity: low
|
|
266
|
-
└── Track and fix during regular dependency updates
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**Key questions:**
|
|
270
|
-
|
|
271
|
-
- Is the vulnerable function actually called in your code path?
|
|
272
|
-
- Is the dependency a runtime dependency or dev-only?
|
|
273
|
-
- Is the vulnerability exploitable given your deployment context (e.g., a
|
|
274
|
-
server-side vulnerability in a client-only app)?
|
|
275
|
-
|
|
276
|
-
When you defer a fix, document the reason and set a review date.
|
|
277
|
-
|
|
278
|
-
## Rate Limiting
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
import rateLimit from 'express-rate-limit';
|
|
282
|
-
|
|
283
|
-
// General API rate limit
|
|
284
|
-
app.use(
|
|
285
|
-
'/api/',
|
|
286
|
-
rateLimit({
|
|
287
|
-
windowMs: 15 * 60 * 1000,
|
|
288
|
-
max: 100,
|
|
289
|
-
standardHeaders: true,
|
|
290
|
-
legacyHeaders: false,
|
|
291
|
-
}),
|
|
292
|
-
);
|
|
293
|
-
|
|
294
|
-
// Stricter limit for auth endpoints (the rule MUSTs rate-limiting on auth)
|
|
295
|
-
app.use(
|
|
296
|
-
'/api/auth/',
|
|
297
|
-
rateLimit({
|
|
298
|
-
windowMs: 15 * 60 * 1000,
|
|
299
|
-
max: 10,
|
|
300
|
-
}),
|
|
301
|
-
);
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
## Secrets Management Layout
|
|
305
|
-
|
|
306
|
-
See [security-baseline § Secrets Management](../../../rules/security-baseline.md#secrets-management).
|
|
307
|
-
|
|
308
|
-
```text
|
|
309
|
-
.env files:
|
|
310
|
-
├── .env.example → Committed (template with placeholder values)
|
|
311
|
-
├── .env → NOT committed (contains real secrets)
|
|
312
|
-
└── .env.local → NOT committed (local overrides)
|
|
313
|
-
|
|
314
|
-
.gitignore must include:
|
|
315
|
-
.env
|
|
316
|
-
.env.local
|
|
317
|
-
.env.*.local
|
|
318
|
-
*.pem
|
|
319
|
-
*.key
|
|
320
|
-
```
|
|
321
|
-
|
|
322
|
-
**Always check before committing:**
|
|
323
|
-
|
|
324
|
-
```bash
|
|
325
|
-
# Check for accidentally staged secrets
|
|
326
|
-
git diff --cached | grep -i "password\|secret\|api_key\|token"
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
## Security Review Checklist
|
|
330
|
-
|
|
331
|
-
Use this when reviewing your own change before requesting human review. Each
|
|
332
|
-
item maps to a section in
|
|
333
|
-
[`security-baseline.md`](../../../rules/security-baseline.md).
|
|
334
|
-
|
|
335
|
-
```markdown
|
|
336
|
-
### Authentication
|
|
337
|
-
|
|
338
|
-
- [ ] Passwords hashed with bcrypt/scrypt/argon2 (salt rounds ≥ 12)
|
|
339
|
-
- [ ] Session tokens are httpOnly, secure, sameSite
|
|
340
|
-
- [ ] Login has rate limiting
|
|
341
|
-
- [ ] Password reset tokens expire
|
|
342
|
-
|
|
343
|
-
### Authorization
|
|
344
|
-
|
|
345
|
-
- [ ] Every endpoint checks user permissions
|
|
346
|
-
- [ ] Users can only access their own resources
|
|
347
|
-
- [ ] Admin actions require admin role verification
|
|
348
|
-
|
|
349
|
-
### Input
|
|
350
|
-
|
|
351
|
-
- [ ] All user input validated at the boundary
|
|
352
|
-
- [ ] SQL queries are parameterized
|
|
353
|
-
- [ ] HTML output is encoded/escaped
|
|
354
|
-
|
|
355
|
-
### Data
|
|
356
|
-
|
|
357
|
-
- [ ] No secrets in code or version control
|
|
358
|
-
- [ ] Sensitive fields excluded from API responses
|
|
359
|
-
- [ ] PII encrypted at rest (if applicable)
|
|
360
|
-
|
|
361
|
-
### Infrastructure
|
|
362
|
-
|
|
363
|
-
- [ ] Security headers configured (CSP, HSTS, etc.)
|
|
364
|
-
- [ ] CORS restricted to known origins
|
|
365
|
-
- [ ] Dependencies audited for vulnerabilities
|
|
366
|
-
- [ ] Error messages don't expose internals
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Common Rationalizations
|
|
370
|
-
|
|
371
|
-
| Rationalization | Reality |
|
|
372
|
-
| --------------------------------------------------- | ------------------------------------------------------------------------------- |
|
|
373
|
-
| "This is an internal tool, security doesn't matter" | Internal tools get compromised. Attackers target the weakest link. |
|
|
374
|
-
| "We'll add security later" | Security retrofitting is 10x harder than building it in. Add it now. |
|
|
375
|
-
| "No one would try to exploit this" | Automated scanners will find it. Security by obscurity is not security. |
|
|
376
|
-
| "The framework handles security" | Frameworks provide tools, not guarantees. You still need to use them correctly. |
|
|
377
|
-
| "It's just a prototype" | Prototypes become production. Security habits from day one. |
|
|
378
|
-
|
|
379
|
-
## Red Flags
|
|
380
|
-
|
|
381
|
-
- User input passed directly to database queries, shell commands, or HTML
|
|
382
|
-
rendering
|
|
383
|
-
- Secrets in source code or commit history
|
|
384
|
-
- API endpoints without authentication or authorization checks
|
|
385
|
-
- Missing CORS configuration or wildcard (`*`) origins
|
|
386
|
-
- No rate limiting on authentication endpoints
|
|
387
|
-
- Stack traces or internal errors exposed to users
|
|
388
|
-
- Dependencies with known critical vulnerabilities
|
|
389
|
-
|
|
390
|
-
## Verification
|
|
391
|
-
|
|
392
|
-
After implementing security-relevant code, confirm against the rule:
|
|
393
|
-
|
|
394
|
-
- [ ] `npm audit` shows no critical or high vulnerabilities
|
|
395
|
-
- [ ] No secrets in source code or git history
|
|
396
|
-
- [ ] All user input validated at system boundaries
|
|
397
|
-
- [ ] Authentication and authorization checked on every protected endpoint
|
|
398
|
-
- [ ] Security headers present in response (check with browser DevTools)
|
|
399
|
-
- [ ] Error responses don't expose internal details
|
|
400
|
-
- [ ] Rate limiting active on auth endpoints
|
|
34
|
+
## Long-form reference — read on demand
|
|
35
|
+
|
|
36
|
+
The capsule above is the contract and the whole always-read surface of this
|
|
37
|
+
skill. The long-form material behind it — patterns, worked examples,
|
|
38
|
+
checklists, and rationalizations — lives in the on-demand sibling
|
|
39
|
+
[`reference.md`](reference.md), matching the split the always-on rules already
|
|
40
|
+
use ([`rules/git-conventions.md`](../../../rules/git-conventions.md) ⇄
|
|
41
|
+
[`git-conventions-reference.md`](../../../rules/git-conventions-reference.md)).
|
|
42
|
+
Activating this skill costs the capsule; open a section below only when the
|
|
43
|
+
task actually engages it.
|
|
44
|
+
|
|
45
|
+
- [When to Use](reference.md#when-to-use)
|
|
46
|
+
- [Security Surfacing, Not Runtime Pause](reference.md#security-surfacing-not-runtime-pause)
|
|
47
|
+
- [OWASP Top 10 Prevention Patterns](reference.md#owasp-top-10-prevention-patterns)
|
|
48
|
+
- [Input Validation Patterns](reference.md#input-validation-patterns)
|
|
49
|
+
- [Triaging npm audit Results](reference.md#triaging-npm-audit-results)
|
|
50
|
+
- [Rate Limiting](reference.md#rate-limiting)
|
|
51
|
+
- [Secrets Management Layout](reference.md#secrets-management-layout)
|
|
52
|
+
- [Security Review Checklist](reference.md#security-review-checklist)
|
|
53
|
+
- [Common Rationalizations](reference.md#common-rationalizations)
|
|
54
|
+
- [Red Flags](reference.md#red-flags)
|
|
55
|
+
- [Verification](reference.md#verification)
|