mandrel 2.0.0 → 2.2.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 +59 -28
- package/.agents/agents/acceptance-critic.md +20 -9
- package/.agents/agents/story-worker.md +45 -48
- package/.agents/audit-checklists/performance.md +1 -1
- package/.agents/docs/SDLC.md +60 -46
- package/.agents/docs/agentrc-reference.json +8 -13
- package/.agents/docs/configuration.md +33 -57
- package/.agents/docs/execution-reference.md +39 -10
- package/.agents/docs/quality-gates.md +17 -19
- package/.agents/docs/workflows.md +6 -6
- package/.agents/instructions.md +64 -79
- package/.agents/rules/ci-remediation.md +3 -3
- package/.agents/rules/gherkin-standards.md +10 -0
- package/.agents/rules/git-conventions-reference.md +42 -51
- package/.agents/schemas/acceptance-eval-verdict.schema.json +2 -2
- package/.agents/schemas/agentrc.schema.json +35 -46
- 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/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 +24 -68
- package/.agents/scripts/agents-bootstrap-github.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 +1 -1
- package/.agents/scripts/check-workflow-cli-lint.js +91 -0
- 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/audit-suite/selector.js +323 -23
- package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -11
- package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -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 +4 -1
- package/.agents/scripts/lib/checks/index.js +1 -1
- 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 +3 -3
- 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-args.js +23 -2
- package/.agents/scripts/lib/close-validation/gates.js +13 -13
- 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/acceptance-eval.js +2 -2
- package/.agents/scripts/lib/config/delivery-routing.js +7 -6
- package/.agents/scripts/lib/config/explain.js +10 -16
- package/.agents/scripts/lib/config/github.js +7 -5
- package/.agents/scripts/lib/config/limits.js +15 -25
- package/.agents/scripts/lib/config/quality.js +11 -14
- package/.agents/scripts/lib/config/runners.js +8 -21
- package/.agents/scripts/lib/config/temp-paths.js +18 -56
- package/.agents/scripts/lib/config-settings-schema-delivery.js +34 -16
- package/.agents/scripts/lib/config-settings-schema-quality.js +9 -2
- package/.agents/scripts/lib/config-settings-schema.js +48 -22
- package/.agents/scripts/lib/dead-exports-knip.js +105 -0
- package/.agents/scripts/lib/dead-exports-mode.js +51 -0
- package/.agents/scripts/lib/duplicate-search.js +38 -7
- 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 -189
- package/.agents/scripts/lib/gh-exec.js +8 -0
- package/.agents/scripts/lib/git-branch-lifecycle.js +0 -158
- package/.agents/scripts/lib/git-utils.js +0 -14
- package/.agents/scripts/lib/json-utils.js +1 -2
- package/.agents/scripts/lib/label-constants.js +0 -15
- package/.agents/scripts/lib/label-taxonomy.js +1 -12
- package/.agents/scripts/lib/observability/active-story-env.js +42 -163
- 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 +2 -2
- package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
- 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 +43 -45
- package/.agents/scripts/lib/orchestration/change-set.js +103 -0
- package/.agents/scripts/lib/orchestration/code-review.js +70 -191
- package/.agents/scripts/lib/orchestration/consolidation-precondition.js +3 -3
- 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/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 +9 -11
- 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/listeners/README.md +7 -3
- 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/merge-block-class.js +76 -20
- package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
- package/.agents/scripts/lib/orchestration/plan-context.js +116 -33
- package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +26 -36
- package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +31 -22
- package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +16 -6
- package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +173 -25
- package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +280 -100
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +472 -55
- package/.agents/scripts/lib/orchestration/plan-persist/summary.js +21 -16
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +230 -0
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +41 -40
- package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +1 -2
- package/.agents/scripts/lib/orchestration/planning/spec-authoring-grounding.js +1 -1
- package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
- package/.agents/scripts/lib/orchestration/retro-proposals.js +7 -7
- package/.agents/scripts/lib/orchestration/review-depth.js +105 -40
- 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/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 +374 -16
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +24 -0
- 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 +4 -13
- 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 +72 -30
- 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 +12 -8
- 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 +264 -43
- package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
- package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +104 -279
- package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +191 -0
- package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +120 -0
- package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +75 -14
- package/.agents/scripts/lib/orchestration/story-init-remote.js +12 -8
- package/.agents/scripts/lib/orchestration/story-plan-state.js +14 -29
- package/.agents/scripts/lib/orchestration/task-body-validator.js +52 -7
- package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +119 -14
- package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +3 -4
- package/.agents/scripts/lib/orchestration/ticket-validator.js +121 -18
- package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -47
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +19 -32
- package/.agents/scripts/lib/orchestration/ticketing/transition.js +61 -1
- 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 -286
- package/.agents/scripts/lib/preflight-runner.js +2 -2
- 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/skills/parse-skill.js +16 -3
- package/.agents/scripts/lib/story-adjacency.js +8 -7
- package/.agents/scripts/lib/story-body/story-body.js +81 -13
- package/.agents/scripts/lib/templates/decomposer-prompts.js +15 -16
- package/.agents/scripts/lib/test-env.js +14 -1
- package/.agents/scripts/lib/test-tiers.js +0 -3
- package/.agents/scripts/lib/ticket-body-sections.js +0 -14
- package/.agents/scripts/lib/validation-evidence.js +31 -59
- package/.agents/scripts/lib/wave-runner/live-probe.js +315 -0
- package/.agents/scripts/lib/wave-runner/ready-set.js +32 -6
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
- package/.agents/scripts/lib/worktree/lifecycle/reap.js +68 -19
- package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
- package/.agents/scripts/plan-context.js +38 -7
- package/.agents/scripts/plan-critics.js +203 -0
- package/.agents/scripts/plan-persist.js +145 -35
- package/.agents/scripts/plan-run-epilogue.js +83 -38
- 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 +1 -11
- package/.agents/scripts/providers/github/mappers.js +5 -0
- package/.agents/scripts/providers/github/sub-issues.js +0 -47
- package/.agents/scripts/providers/github/tickets.js +33 -153
- package/.agents/scripts/providers/github.js +17 -6
- package/.agents/scripts/quality-preview.js +13 -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 +9 -10
- package/.agents/scripts/single-story-close.js +173 -18
- package/.agents/scripts/single-story-confirm-merge.js +288 -15
- package/.agents/scripts/single-story-init.js +6 -10
- package/.agents/scripts/stories-wave-tick.js +380 -53
- package/.agents/scripts/story-plan.js +3 -3
- package/.agents/scripts/update-ticket-state.js +8 -50
- 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 +3 -3
- package/.agents/skills/core/scope-triage/SKILL.md +3 -0
- 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 +2 -12
- 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/workflows/audit-architecture.md +3 -4
- package/.agents/workflows/audit-clean-code.md +4 -4
- package/.agents/workflows/audit-documentation.md +4 -5
- package/.agents/workflows/audit-lighthouse.md +8 -0
- package/.agents/workflows/audit-navigability.md +10 -0
- package/.agents/workflows/audit-performance.md +2 -3
- package/.agents/workflows/audit-quality.md +8 -9
- package/.agents/workflows/audit-security.md +1 -2
- package/.agents/workflows/audit-seo.md +10 -0
- package/.agents/workflows/audit-ux-ui.md +7 -0
- package/.agents/workflows/deliver.md +133 -45
- package/.agents/workflows/git-cleanup.md +2 -2
- package/.agents/workflows/git-deliver.md +1 -1
- package/.agents/workflows/helpers/acceptance-self-eval.md +34 -17
- package/.agents/workflows/helpers/code-quality-guardrails.md +15 -12
- package/.agents/workflows/helpers/code-review.md +14 -12
- package/.agents/workflows/helpers/deliver-story-reference.md +73 -32
- package/.agents/workflows/helpers/deliver-story.md +209 -118
- package/.agents/workflows/helpers/parallel-tooling.md +2 -2
- package/.agents/workflows/helpers/worktree-lifecycle.md +28 -32
- package/.agents/workflows/plan.md +239 -19
- package/.agents/workflows/qa-assist.md +6 -6
- package/.agents/workflows/qa-explore.md +3 -3
- package/.agents/workflows/qa-run.md +1 -5
- package/bin/mandrel.js +12 -1
- package/docs/CHANGELOG.md +62 -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 +17 -9
- 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/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +154 -0
- package/package.json +2 -2
- package/.agents/schemas/epic-perf-report.schema.json +0 -89
- 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/story.heartbeat.schema.json +0 -20
- package/.agents/schemas/risk-verdict.schema.json +0 -53
- package/.agents/schemas/story-perf-summary.schema.json +0 -73
- package/.agents/scripts/analyze-execution.js +0 -444
- package/.agents/scripts/check-prepush-recovery.js +0 -90
- 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 -187
- 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/audit-lens-routing.js +0 -128
- package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -273
- package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
- 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/merge-watcher.js +0 -665
- package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
- package/.agents/scripts/lib/orchestration/planning/risk-verdict.js +0 -104
- 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 -21
- 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 -397
- package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
- package/.agents/scripts/lib/orchestration/resolve-plan-run.js +0 -155
- package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
- package/.agents/scripts/lib/orchestration/story-progress/story-run-progress-writer.js +0 -400
- package/.agents/scripts/lib/single-story/confirm-merge-follow-ups.js +0 -36
- package/.agents/scripts/resolve-plan-run.js +0 -117
- package/.agents/skills/core/analyze-execution/SKILL.md +0 -101
|
@@ -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)
|