mindforge-cc 1.0.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/.agent/CLAUDE.md +462 -0
- package/.agent/forge/help.md +7 -0
- package/.agent/forge/init-project.md +32 -0
- package/.agent/forge/plan-phase.md +30 -0
- package/.agent/mindforge/approve.md +18 -0
- package/.agent/mindforge/audit.md +30 -0
- package/.agent/mindforge/benchmark.md +33 -0
- package/.agent/mindforge/complete-milestone.md +18 -0
- package/.agent/mindforge/debug.md +126 -0
- package/.agent/mindforge/discuss-phase.md +138 -0
- package/.agent/mindforge/execute-phase.md +165 -0
- package/.agent/mindforge/health.md +21 -0
- package/.agent/mindforge/help.md +23 -0
- package/.agent/mindforge/init-org.md +131 -0
- package/.agent/mindforge/init-project.md +155 -0
- package/.agent/mindforge/install-skill.md +15 -0
- package/.agent/mindforge/map-codebase.md +298 -0
- package/.agent/mindforge/metrics.md +22 -0
- package/.agent/mindforge/migrate.md +40 -0
- package/.agent/mindforge/milestone.md +12 -0
- package/.agent/mindforge/next.md +105 -0
- package/.agent/mindforge/plan-phase.md +125 -0
- package/.agent/mindforge/plugins.md +40 -0
- package/.agent/mindforge/pr-review.md +41 -0
- package/.agent/mindforge/profile-team.md +23 -0
- package/.agent/mindforge/publish-skill.md +19 -0
- package/.agent/mindforge/quick.md +135 -0
- package/.agent/mindforge/release.md +10 -0
- package/.agent/mindforge/retrospective.md +26 -0
- package/.agent/mindforge/review.md +157 -0
- package/.agent/mindforge/security-scan.md +233 -0
- package/.agent/mindforge/ship.md +100 -0
- package/.agent/mindforge/skills.md +141 -0
- package/.agent/mindforge/status.md +104 -0
- package/.agent/mindforge/sync-confluence.md +11 -0
- package/.agent/mindforge/sync-jira.md +12 -0
- package/.agent/mindforge/tokens.md +8 -0
- package/.agent/mindforge/update.md +42 -0
- package/.agent/mindforge/verify-phase.md +62 -0
- package/.agent/mindforge/workspace.md +29 -0
- package/.claude/CLAUDE.md +462 -0
- package/.claude/commands/forge/help.md +7 -0
- package/.claude/commands/forge/init-project.md +32 -0
- package/.claude/commands/forge/plan-phase.md +30 -0
- package/.claude/commands/mindforge/approve.md +18 -0
- package/.claude/commands/mindforge/audit.md +30 -0
- package/.claude/commands/mindforge/benchmark.md +33 -0
- package/.claude/commands/mindforge/complete-milestone.md +18 -0
- package/.claude/commands/mindforge/debug.md +126 -0
- package/.claude/commands/mindforge/discuss-phase.md +138 -0
- package/.claude/commands/mindforge/execute-phase.md +165 -0
- package/.claude/commands/mindforge/health.md +21 -0
- package/.claude/commands/mindforge/help.md +23 -0
- package/.claude/commands/mindforge/init-org.md +131 -0
- package/.claude/commands/mindforge/init-project.md +155 -0
- package/.claude/commands/mindforge/install-skill.md +15 -0
- package/.claude/commands/mindforge/map-codebase.md +298 -0
- package/.claude/commands/mindforge/metrics.md +22 -0
- package/.claude/commands/mindforge/migrate.md +40 -0
- package/.claude/commands/mindforge/milestone.md +12 -0
- package/.claude/commands/mindforge/next.md +105 -0
- package/.claude/commands/mindforge/plan-phase.md +125 -0
- package/.claude/commands/mindforge/plugins.md +40 -0
- package/.claude/commands/mindforge/pr-review.md +41 -0
- package/.claude/commands/mindforge/profile-team.md +23 -0
- package/.claude/commands/mindforge/publish-skill.md +19 -0
- package/.claude/commands/mindforge/quick.md +135 -0
- package/.claude/commands/mindforge/release.md +10 -0
- package/.claude/commands/mindforge/retrospective.md +26 -0
- package/.claude/commands/mindforge/review.md +157 -0
- package/.claude/commands/mindforge/security-scan.md +233 -0
- package/.claude/commands/mindforge/ship.md +100 -0
- package/.claude/commands/mindforge/skills.md +141 -0
- package/.claude/commands/mindforge/status.md +104 -0
- package/.claude/commands/mindforge/sync-confluence.md +11 -0
- package/.claude/commands/mindforge/sync-jira.md +12 -0
- package/.claude/commands/mindforge/tokens.md +8 -0
- package/.claude/commands/mindforge/update.md +42 -0
- package/.claude/commands/mindforge/verify-phase.md +62 -0
- package/.claude/commands/mindforge/workspace.md +29 -0
- package/.forge/org/CONVENTIONS.md +0 -0
- package/.forge/org/ORG.md +0 -0
- package/.forge/org/SECURITY.md +0 -0
- package/.forge/org/TOOLS.md +0 -0
- package/.forge/personas/analyst.md +0 -0
- package/.forge/personas/architect.md +0 -0
- package/.forge/personas/debug-specialist.md +0 -0
- package/.forge/personas/developer.md +26 -0
- package/.forge/personas/qa-engineer.md +0 -0
- package/.forge/personas/release-manager.md +0 -0
- package/.forge/personas/security-reviewer.md +33 -0
- package/.forge/personas/tech-writer.md +0 -0
- package/.forge/skills/api-design/SKILL.md +0 -0
- package/.forge/skills/code-quality/SKILL.md +0 -0
- package/.forge/skills/documentation/SKILL.md +0 -0
- package/.forge/skills/security-review/SKILL.md +23 -0
- package/.forge/skills/testing-standards/SKILL.md +27 -0
- package/.github/workflows/mindforge-ci.yml +224 -0
- package/.gitlab-ci-mindforge.yml +18 -0
- package/.mindforge/MINDFORGE-SCHEMA.json +165 -0
- package/.mindforge/audit/AUDIT-SCHEMA.md +451 -0
- package/.mindforge/ci/ci-config-schema.md +21 -0
- package/.mindforge/ci/ci-mode.md +179 -0
- package/.mindforge/ci/github-actions-adapter.md +224 -0
- package/.mindforge/ci/gitlab-ci-adapter.md +31 -0
- package/.mindforge/ci/jenkins-adapter.md +44 -0
- package/.mindforge/distribution/registry-client.md +166 -0
- package/.mindforge/distribution/registry-schema.md +96 -0
- package/.mindforge/distribution/skill-publisher.md +44 -0
- package/.mindforge/distribution/skill-validator.md +74 -0
- package/.mindforge/engine/compaction-protocol.md +182 -0
- package/.mindforge/engine/context-injector.md +128 -0
- package/.mindforge/engine/dependency-parser.md +113 -0
- package/.mindforge/engine/skills/conflict-resolver.md +69 -0
- package/.mindforge/engine/skills/loader.md +184 -0
- package/.mindforge/engine/skills/registry.md +98 -0
- package/.mindforge/engine/skills/versioning.md +75 -0
- package/.mindforge/engine/verification-pipeline.md +111 -0
- package/.mindforge/engine/wave-executor.md +235 -0
- package/.mindforge/governance/GOVERNANCE-CONFIG.md +17 -0
- package/.mindforge/governance/approval-workflow.md +37 -0
- package/.mindforge/governance/change-classifier.md +63 -0
- package/.mindforge/governance/compliance-gates.md +31 -0
- package/.mindforge/integrations/confluence.md +27 -0
- package/.mindforge/integrations/connection-manager.md +163 -0
- package/.mindforge/integrations/github.md +25 -0
- package/.mindforge/integrations/gitlab.md +13 -0
- package/.mindforge/integrations/jira.md +102 -0
- package/.mindforge/integrations/slack.md +41 -0
- package/.mindforge/intelligence/antipattern-detector.md +75 -0
- package/.mindforge/intelligence/difficulty-scorer.md +55 -0
- package/.mindforge/intelligence/health-engine.md +208 -0
- package/.mindforge/intelligence/skill-gap-analyser.md +40 -0
- package/.mindforge/intelligence/smart-compaction.md +71 -0
- package/.mindforge/metrics/METRICS-SCHEMA.md +42 -0
- package/.mindforge/metrics/quality-tracker.md +32 -0
- package/.mindforge/monorepo/cross-package-planner.md +114 -0
- package/.mindforge/monorepo/dependency-graph-builder.md +32 -0
- package/.mindforge/monorepo/workspace-detector.md +129 -0
- package/.mindforge/org/CONVENTIONS.md +62 -0
- package/.mindforge/org/ORG.md +51 -0
- package/.mindforge/org/SECURITY.md +50 -0
- package/.mindforge/org/TOOLS.md +53 -0
- package/.mindforge/org/integrations/INTEGRATIONS-CONFIG.md +58 -0
- package/.mindforge/org/skills/MANIFEST.md +38 -0
- package/.mindforge/personas/analyst.md +52 -0
- package/.mindforge/personas/architect.md +75 -0
- package/.mindforge/personas/debug-specialist.md +52 -0
- package/.mindforge/personas/developer.md +85 -0
- package/.mindforge/personas/overrides/README.md +85 -0
- package/.mindforge/personas/qa-engineer.md +61 -0
- package/.mindforge/personas/release-manager.md +76 -0
- package/.mindforge/personas/security-reviewer.md +91 -0
- package/.mindforge/personas/tech-writer.md +51 -0
- package/.mindforge/plugins/PLUGINS-MANIFEST.md +23 -0
- package/.mindforge/plugins/plugin-loader.md +93 -0
- package/.mindforge/plugins/plugin-registry.md +44 -0
- package/.mindforge/plugins/plugin-schema.md +68 -0
- package/.mindforge/pr-review/ai-reviewer.md +266 -0
- package/.mindforge/pr-review/finding-formatter.md +46 -0
- package/.mindforge/pr-review/review-prompt-templates.md +44 -0
- package/.mindforge/production/compatibility-layer.md +39 -0
- package/.mindforge/production/migration-engine.md +52 -0
- package/.mindforge/production/production-checklist.md +165 -0
- package/.mindforge/production/token-optimiser.md +68 -0
- package/.mindforge/skills/accessibility/SKILL.md +106 -0
- package/.mindforge/skills/api-design/SKILL.md +98 -0
- package/.mindforge/skills/code-quality/SKILL.md +88 -0
- package/.mindforge/skills/data-privacy/SKILL.md +126 -0
- package/.mindforge/skills/database-patterns/SKILL.md +192 -0
- package/.mindforge/skills/documentation/SKILL.md +91 -0
- package/.mindforge/skills/incident-response/SKILL.md +180 -0
- package/.mindforge/skills/performance/SKILL.md +120 -0
- package/.mindforge/skills/security-review/SKILL.md +83 -0
- package/.mindforge/skills/testing-standards/SKILL.md +97 -0
- package/.mindforge/team/TEAM-PROFILE.md +42 -0
- package/.mindforge/team/multi-handoff.md +23 -0
- package/.mindforge/team/profiles/README.md +13 -0
- package/.mindforge/team/session-merger.md +18 -0
- package/.planning/ARCHITECTURE.md +0 -0
- package/.planning/AUDIT.jsonl +0 -0
- package/.planning/HANDOFF.json +28 -0
- package/.planning/PROJECT.md +33 -0
- package/.planning/RELEASE-CHECKLIST.md +68 -0
- package/.planning/REQUIREMENTS.md +0 -0
- package/.planning/ROADMAP.md +0 -0
- package/.planning/STATE.md +31 -0
- package/.planning/approvals/.gitkeep +1 -0
- package/.planning/archive/.gitkeep +1 -0
- package/.planning/audit-archive/.gitkeep +1 -0
- package/.planning/decisions/.gitkeep +0 -0
- package/.planning/decisions/ADR-001-handoff-tracking.md +41 -0
- package/.planning/decisions/ADR-002-markdown-commands.md +46 -0
- package/.planning/decisions/ADR-003-skills-trigger-model.md +37 -0
- package/.planning/decisions/ADR-004-wave-parallelism-model.md +45 -0
- package/.planning/decisions/ADR-005-append-only-audit-log.md +51 -0
- package/.planning/decisions/ADR-006-tiered-skills-system.md +22 -0
- package/.planning/decisions/ADR-007-trigger-keyword-model.md +22 -0
- package/.planning/decisions/ADR-008-just-in-time-skill-loading.md +29 -0
- package/.planning/decisions/ADR-009-enterprise-integration-retry-policy.md +8 -0
- package/.planning/decisions/ADR-010-governance-tier-escalation.md +8 -0
- package/.planning/decisions/ADR-011-multi-developer-handoff-contract.md +8 -0
- package/.planning/decisions/ADR-012-intelligence-feedback-loops.md +19 -0
- package/.planning/decisions/ADR-013-mindforge-md-constitution.md +16 -0
- package/.planning/decisions/ADR-014-metrics-as-signals-not-evaluation.md +15 -0
- package/.planning/decisions/ADR-015-npm-based-skill-registry.md +26 -0
- package/.planning/decisions/ADR-016-ci-exit-code-0-on-timeout.md +27 -0
- package/.planning/decisions/ADR-017-sdk-localhost-only.md +28 -0
- package/.planning/decisions/ADR-018-installer-self-install-detection.md +15 -0
- package/.planning/decisions/ADR-019-self-update-scope-preservation.md +14 -0
- package/.planning/decisions/ADR-020-v1.0.0-stable-interface-contract.md +23 -0
- package/.planning/jira-sync.json +9 -0
- package/.planning/milestones/.gitkeep +1 -0
- package/.planning/phases/day1/REVIEW-DAY1.md +50 -0
- package/.planning/phases/day1/SECURITY-REVIEW-DAY1.md +15 -0
- package/.planning/phases/day2/REVIEW-DAY2.md +521 -0
- package/.planning/phases/day3/REVIEW-DAY3.md +234 -0
- package/.planning/slack-threads.json +6 -0
- package/CHANGELOG.md +175 -0
- package/LICENSE +21 -0
- package/MINDFORGE.md +76 -0
- package/README.md +182 -0
- package/RELEASENOTES.md +41 -0
- package/SECURITY.md +4 -0
- package/bin/install.js +120 -0
- package/bin/installer-core.js +292 -0
- package/bin/migrations/0.1.0-to-0.5.0.js +37 -0
- package/bin/migrations/0.5.0-to-0.6.0.js +17 -0
- package/bin/migrations/0.6.0-to-1.0.0.js +100 -0
- package/bin/migrations/migrate.js +151 -0
- package/bin/migrations/schema-versions.js +64 -0
- package/bin/updater/changelog-fetcher.js +62 -0
- package/bin/updater/self-update.js +169 -0
- package/bin/updater/version-comparator.js +68 -0
- package/bin/validate-config.js +92 -0
- package/bin/wizard/config-generator.js +112 -0
- package/bin/wizard/environment-detector.js +76 -0
- package/bin/wizard/setup-wizard.js +237 -0
- package/docs/Context/Master-Context.md +701 -0
- package/docs/architecture/README.md +35 -0
- package/docs/architecture/decision-records-index.md +26 -0
- package/docs/ci-cd-integration.md +30 -0
- package/docs/ci-quickstart.md +78 -0
- package/docs/commands-reference.md +11 -0
- package/docs/contributing/CONTRIBUTING.md +38 -0
- package/docs/contributing/plugin-authoring.md +50 -0
- package/docs/contributing/skill-authoring.md +41 -0
- package/docs/enterprise-setup.md +25 -0
- package/docs/faq.md +38 -0
- package/docs/getting-started.md +36 -0
- package/docs/governance-guide.md +23 -0
- package/docs/mindforge-md-reference.md +53 -0
- package/docs/monorepo-guide.md +26 -0
- package/docs/persona-customisation.md +56 -0
- package/docs/quick-verify.md +33 -0
- package/docs/reference/audit-events.md +53 -0
- package/docs/reference/commands.md +82 -0
- package/docs/reference/config-reference.md +64 -0
- package/docs/reference/sdk-api.md +48 -0
- package/docs/reference/skills-api.md +57 -0
- package/docs/release-checklist-guide.md +37 -0
- package/docs/requirements.md +29 -0
- package/docs/sdk-reference.md +27 -0
- package/docs/security/SECURITY.md +42 -0
- package/docs/security/penetration-test-results.md +31 -0
- package/docs/security/threat-model.md +142 -0
- package/docs/skills-authoring-guide.md +119 -0
- package/docs/skills-publishing-guide.md +21 -0
- package/docs/team-setup-guide.md +21 -0
- package/docs/troubleshooting.md +119 -0
- package/docs/tutorial.md +195 -0
- package/docs/upgrade.md +44 -0
- package/docs/user-guide.md +131 -0
- package/docs/usp-features.md +214 -0
- package/eslint.config.mjs +31 -0
- package/examples/starter-project/.planning/AUDIT.jsonl +1 -0
- package/examples/starter-project/.planning/HANDOFF.json +23 -0
- package/examples/starter-project/.planning/PROJECT.md +27 -0
- package/examples/starter-project/.planning/STATE.md +10 -0
- package/examples/starter-project/MINDFORGE.md +40 -0
- package/examples/starter-project/README.md +14 -0
- package/implementation-roadmap/day-1-imp/DAY1-HARDEN.md +823 -0
- package/implementation-roadmap/day-1-imp/DAY1-IMPLEMENT.md +2459 -0
- package/implementation-roadmap/day-1-imp/DAY1-REVIEW.md +288 -0
- package/implementation-roadmap/day-2-imp/DAY2-HARDEN.md +954 -0
- package/implementation-roadmap/day-2-imp/DAY2-IMPLEMENT.md +2347 -0
- package/implementation-roadmap/day-2-imp/DAY2-REVIEW.md +422 -0
- package/implementation-roadmap/day-3-imp/DAY3-HARDEN.md +870 -0
- package/implementation-roadmap/day-3-imp/DAY3-IMPLEMENT.md +2798 -0
- package/implementation-roadmap/day-3-imp/DAY3-REVIEW.md +484 -0
- package/implementation-roadmap/day-4-imp/DAY4-HARDEN.md +1087 -0
- package/implementation-roadmap/day-4-imp/DAY4-IMPLEMENT.md +2874 -0
- package/implementation-roadmap/day-4-imp/DAY4-REVIEW.md +386 -0
- package/implementation-roadmap/day-5-imp/DAY5-HARDEN.md +1078 -0
- package/implementation-roadmap/day-5-imp/DAY5-IMPLEMENT.md +3151 -0
- package/implementation-roadmap/day-5-imp/DAY5-REVIEW.md +345 -0
- package/implementation-roadmap/day-6-imp/DAY6-COMPLETE.md +3919 -0
- package/implementation-roadmap/day-7-imp-prod/DAY7-PRODUCTION-FINAL.md +4513 -0
- package/package.json +31 -0
- package/sdk/README.md +69 -0
- package/sdk/eslint.config.mjs +34 -0
- package/sdk/package-lock.json +1507 -0
- package/sdk/package.json +30 -0
- package/sdk/src/client.ts +133 -0
- package/sdk/src/commands.ts +63 -0
- package/sdk/src/events.ts +166 -0
- package/sdk/src/index.ts +22 -0
- package/sdk/src/types.ts +87 -0
- package/sdk/tsconfig.json +13 -0
- package/tests/audit.test.js +206 -0
- package/tests/ci-mode.test.js +162 -0
- package/tests/compaction.test.js +161 -0
- package/tests/distribution.test.js +205 -0
- package/tests/e2e.test.js +618 -0
- package/tests/governance.test.js +130 -0
- package/tests/install.test.js +209 -0
- package/tests/integrations.test.js +128 -0
- package/tests/intelligence.test.js +117 -0
- package/tests/metrics.test.js +96 -0
- package/tests/migration.test.js +309 -0
- package/tests/production.test.js +416 -0
- package/tests/sdk.test.js +200 -0
- package/tests/skills-platform.test.js +403 -0
- package/tests/wave-engine.test.js +338 -0
|
@@ -0,0 +1,2874 @@
|
|
|
1
|
+
# MindForge — Day 4 Implementation Prompt
|
|
2
|
+
# Branch: `feat/mindforge-enterprise-integrations`
|
|
3
|
+
# Prerequisite: `feat/mindforge-skills-platform` merged to `main`
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## BRANCH SETUP (run before anything else)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
git checkout main
|
|
11
|
+
git pull origin main
|
|
12
|
+
git checkout -b feat/mindforge-enterprise-integrations
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Verify all prior days are present and passing:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
ls .mindforge/engine/skills/loader.md # Day 3 skills engine
|
|
19
|
+
ls .mindforge/skills/performance/SKILL.md # Day 3 skill packs
|
|
20
|
+
ls .claude/commands/mindforge/review.md # Day 3 commands
|
|
21
|
+
cat package.json | grep '"version"' # Must be "0.3.0"
|
|
22
|
+
node tests/install.test.js && \
|
|
23
|
+
node tests/wave-engine.test.js && \
|
|
24
|
+
node tests/audit.test.js && \
|
|
25
|
+
node tests/compaction.test.js && \
|
|
26
|
+
node tests/skills-platform.test.js
|
|
27
|
+
# All 5 suites must pass before Day 4 begins
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## DAY 4 SCOPE
|
|
33
|
+
|
|
34
|
+
Day 4 builds the **Enterprise Integration & Governance Layer** — the components
|
|
35
|
+
that transform MindForge from a personal productivity tool into a system that
|
|
36
|
+
entire engineering organisations can adopt, govern, and audit.
|
|
37
|
+
|
|
38
|
+
| Component | Description |
|
|
39
|
+
|---|---|
|
|
40
|
+
| Jira Integration | Bidirectional sync: phases ↔ epics, tasks ↔ tickets, status propagation |
|
|
41
|
+
| Confluence Integration | Publish ARCHITECTURE.md, ADRs, phase docs to team wiki |
|
|
42
|
+
| Slack Integration | Notifications: phase completion, security findings, approvals, blockers |
|
|
43
|
+
| GitHub/GitLab Enhanced Ship | PR templates, reviewer assignment, branch protection checks |
|
|
44
|
+
| Multi-Developer HANDOFF | Per-developer session files, team state merging, conflict resolution |
|
|
45
|
+
| Governance Layer | Three-tier approval workflows, compliance gates, change classification |
|
|
46
|
+
| AUDIT.jsonl Archiving | Rotate after 10,000 lines, archive to `.planning/audit-archive/` |
|
|
47
|
+
| `/mindforge:audit` command | Query audit log: filter by phase, event, date, agent, severity |
|
|
48
|
+
| `/mindforge:milestone` command | Group phases into milestones, track milestone health |
|
|
49
|
+
| `/mindforge:complete-milestone` | Archive milestone, create release tag, generate milestone report |
|
|
50
|
+
| `/mindforge:approve` command | Human approval workflow for Tier 2 and Tier 3 changes |
|
|
51
|
+
| Day 4 test suite | `tests/integrations.test.js`, `tests/governance.test.js` |
|
|
52
|
+
|
|
53
|
+
**Do not** implement on Day 4:
|
|
54
|
+
- GUI dashboard or web interface (Day 5+)
|
|
55
|
+
- Multi-repo / monorepo support (Day 5+)
|
|
56
|
+
- AI-generated PR reviews (Day 5+)
|
|
57
|
+
- SSO / SAML authentication for integrations (Day 5+)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## TASK 1 — Scaffold Day 4 directory additions
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Enterprise integrations engine
|
|
65
|
+
mkdir -p .mindforge/integrations
|
|
66
|
+
touch .mindforge/integrations/jira.md
|
|
67
|
+
touch .mindforge/integrations/confluence.md
|
|
68
|
+
touch .mindforge/integrations/slack.md
|
|
69
|
+
touch .mindforge/integrations/github.md
|
|
70
|
+
touch .mindforge/integrations/gitlab.md
|
|
71
|
+
touch .mindforge/integrations/connection-manager.md
|
|
72
|
+
|
|
73
|
+
# Governance engine
|
|
74
|
+
mkdir -p .mindforge/governance
|
|
75
|
+
touch .mindforge/governance/approval-workflow.md
|
|
76
|
+
touch .mindforge/governance/change-classifier.md
|
|
77
|
+
touch .mindforge/governance/compliance-gates.md
|
|
78
|
+
touch .mindforge/governance/GOVERNANCE-CONFIG.md
|
|
79
|
+
|
|
80
|
+
# Multi-developer session management
|
|
81
|
+
mkdir -p .mindforge/team
|
|
82
|
+
touch .mindforge/team/multi-handoff.md
|
|
83
|
+
touch .mindforge/team/session-merger.md
|
|
84
|
+
|
|
85
|
+
# Audit archiving
|
|
86
|
+
mkdir -p .planning/audit-archive
|
|
87
|
+
|
|
88
|
+
# New commands
|
|
89
|
+
touch .claude/commands/mindforge/audit.md
|
|
90
|
+
touch .claude/commands/mindforge/milestone.md
|
|
91
|
+
touch .claude/commands/mindforge/complete-milestone.md
|
|
92
|
+
touch .claude/commands/mindforge/approve.md
|
|
93
|
+
touch .claude/commands/mindforge/sync-jira.md
|
|
94
|
+
touch .claude/commands/mindforge/sync-confluence.md
|
|
95
|
+
|
|
96
|
+
# Mirror to Antigravity
|
|
97
|
+
for cmd in audit milestone complete-milestone approve sync-jira sync-confluence; do
|
|
98
|
+
cp .claude/commands/mindforge/${cmd}.md .agent/mindforge/${cmd}.md
|
|
99
|
+
done
|
|
100
|
+
|
|
101
|
+
# Integration config templates
|
|
102
|
+
mkdir -p .mindforge/org/integrations
|
|
103
|
+
touch .mindforge/org/integrations/INTEGRATIONS-CONFIG.md
|
|
104
|
+
|
|
105
|
+
# Tests
|
|
106
|
+
touch tests/integrations.test.js
|
|
107
|
+
touch tests/governance.test.js
|
|
108
|
+
|
|
109
|
+
# Docs
|
|
110
|
+
touch docs/enterprise-setup.md
|
|
111
|
+
touch docs/governance-guide.md
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Commit:**
|
|
115
|
+
```bash
|
|
116
|
+
git add .
|
|
117
|
+
git commit -m "chore(day4): scaffold Day 4 enterprise integrations directory structure"
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## TASK 2 — Write the Integration Connection Manager
|
|
123
|
+
|
|
124
|
+
The connection manager is the security-first layer that handles all credentials,
|
|
125
|
+
connection validation, and integration availability detection.
|
|
126
|
+
|
|
127
|
+
### `.mindforge/integrations/connection-manager.md`
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
# MindForge Integrations — Connection Manager
|
|
131
|
+
|
|
132
|
+
## Purpose
|
|
133
|
+
Centralise all integration credential management, availability detection,
|
|
134
|
+
and connection health checking. No integration should ever handle credentials
|
|
135
|
+
directly — all credential access goes through the connection manager.
|
|
136
|
+
|
|
137
|
+
## Credential storage principles
|
|
138
|
+
|
|
139
|
+
### Rule 1 — Never store credentials in MindForge files
|
|
140
|
+
Integration credentials MUST be stored in environment variables or a secrets
|
|
141
|
+
manager. MindForge configuration files store only: service URLs, workspace
|
|
142
|
+
identifiers, and non-sensitive configuration. Never API tokens or passwords.
|
|
143
|
+
|
|
144
|
+
### Rule 2 — Environment variable naming convention
|
|
145
|
+
```bash
|
|
146
|
+
# Jira
|
|
147
|
+
JIRA_BASE_URL=https://your-org.atlassian.net
|
|
148
|
+
JIRA_USER_EMAIL=engineer@your-org.com
|
|
149
|
+
JIRA_API_TOKEN=<from environment — never in config files>
|
|
150
|
+
|
|
151
|
+
# Confluence
|
|
152
|
+
CONFLUENCE_BASE_URL=https://your-org.atlassian.net/wiki
|
|
153
|
+
CONFLUENCE_SPACE_KEY=ENG
|
|
154
|
+
CONFLUENCE_API_TOKEN=<from environment>
|
|
155
|
+
|
|
156
|
+
# Slack
|
|
157
|
+
SLACK_BOT_TOKEN=<from environment — xoxb-...>
|
|
158
|
+
SLACK_WEBHOOK_URL=<from environment — optional, for simple notifications>
|
|
159
|
+
SLACK_CHANNEL_ID=<channel ID, not name — safe to store in config>
|
|
160
|
+
|
|
161
|
+
# GitHub
|
|
162
|
+
GITHUB_TOKEN=<from environment — ghp_...>
|
|
163
|
+
GITHUB_REPO=owner/repository-name
|
|
164
|
+
GITHUB_DEFAULT_REVIEWERS=user1,user2
|
|
165
|
+
|
|
166
|
+
# GitLab
|
|
167
|
+
GITLAB_TOKEN=<from environment>
|
|
168
|
+
GITLAB_PROJECT_ID=<numeric — safe to store in config>
|
|
169
|
+
GITLAB_DEFAULT_REVIEWERS=user1,user2
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Rule 3 — Config file stores non-sensitive values only
|
|
173
|
+
`.mindforge/org/integrations/INTEGRATIONS-CONFIG.md` stores:
|
|
174
|
+
- Service base URLs (not credentials)
|
|
175
|
+
- Workspace and project identifiers
|
|
176
|
+
- Channel IDs (not tokens)
|
|
177
|
+
- Behaviour configuration (what to sync, notification preferences)
|
|
178
|
+
|
|
179
|
+
## Connection availability detection
|
|
180
|
+
|
|
181
|
+
Before any integration action, verify the integration is available:
|
|
182
|
+
|
|
183
|
+
### Detection protocol
|
|
184
|
+
```bash
|
|
185
|
+
# Step 1: Check environment variable exists
|
|
186
|
+
# (do not check the value — just existence)
|
|
187
|
+
if [ -z "${JIRA_API_TOKEN}" ]; then
|
|
188
|
+
echo "JIRA_API_TOKEN not set. Skipping Jira integration."
|
|
189
|
+
exit 0 # Graceful skip — not an error
|
|
190
|
+
fi
|
|
191
|
+
|
|
192
|
+
# Step 2: Verify config has required non-sensitive values
|
|
193
|
+
# Read INTEGRATIONS-CONFIG.md and verify JIRA_BASE_URL is set
|
|
194
|
+
|
|
195
|
+
# Step 3: Health check — single lightweight API call
|
|
196
|
+
curl -s -o /dev/null -w "%{http_code}" \
|
|
197
|
+
-H "Authorization: Basic $(echo -n "${JIRA_USER_EMAIL}:${JIRA_API_TOKEN}" | base64)" \
|
|
198
|
+
"${JIRA_BASE_URL}/rest/api/3/myself"
|
|
199
|
+
# Expected: 200
|
|
200
|
+
# If 401: credentials invalid
|
|
201
|
+
# If 404: wrong base URL
|
|
202
|
+
# If connection refused: Jira unreachable
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Availability states
|
|
206
|
+
| State | Meaning | MindForge behaviour |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| `available` | Credentials present, health check passed | Proceed with integration |
|
|
209
|
+
| `unconfigured` | No credentials set | Skip integration silently, log to AUDIT |
|
|
210
|
+
| `invalid_credentials` | Credentials present but 401 response | Warn user, skip integration |
|
|
211
|
+
| `unreachable` | Service not responding | Warn user, skip integration |
|
|
212
|
+
| `rate_limited` | 429 response | Wait 60 seconds, retry once |
|
|
213
|
+
|
|
214
|
+
### Credential rotation detection
|
|
215
|
+
If a health check returns 401 on a previously-working integration:
|
|
216
|
+
1. Log AUDIT entry: `{ "event": "integration_credential_expired", "integration": "jira" }`
|
|
217
|
+
2. Alert the user: "Jira credentials appear to have expired. Update JIRA_API_TOKEN
|
|
218
|
+
and run /mindforge:sync-jira to reconnect."
|
|
219
|
+
3. Do not retry with expired credentials.
|
|
220
|
+
|
|
221
|
+
## Integration action logging
|
|
222
|
+
Every integration action (sync, publish, notify) must write to AUDIT.jsonl:
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"id": "uuid-v4",
|
|
226
|
+
"timestamp": "ISO-8601",
|
|
227
|
+
"event": "integration_action",
|
|
228
|
+
"integration": "jira|confluence|slack|github|gitlab",
|
|
229
|
+
"action": "create_ticket|update_ticket|publish_page|send_notification|create_pr",
|
|
230
|
+
"status": "success|failed|skipped",
|
|
231
|
+
"detail": "brief description",
|
|
232
|
+
"external_id": "ticket ID, page ID, PR number — whatever the external system returned"
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## INTEGRATIONS-CONFIG.md template
|
|
237
|
+
|
|
238
|
+
`.mindforge/org/integrations/INTEGRATIONS-CONFIG.md`:
|
|
239
|
+
|
|
240
|
+
```markdown
|
|
241
|
+
# MindForge Integrations Configuration
|
|
242
|
+
# IMPORTANT: This file must NOT contain API tokens, passwords, or credentials.
|
|
243
|
+
# All credentials are stored in environment variables (see connection-manager.md).
|
|
244
|
+
|
|
245
|
+
## Jira Configuration
|
|
246
|
+
JIRA_BASE_URL=https://your-org.atlassian.net
|
|
247
|
+
JIRA_PROJECT_KEY=ENG
|
|
248
|
+
JIRA_EPIC_LABEL=mindforge-phase
|
|
249
|
+
JIRA_STORY_TYPE=Story
|
|
250
|
+
JIRA_BUG_TYPE=Bug
|
|
251
|
+
JIRA_STORY_POINTS_FIELD=story_points
|
|
252
|
+
# Phase-to-epic mapping: MindForge Phase N → Jira Epic
|
|
253
|
+
# Populated automatically by /mindforge:sync-jira
|
|
254
|
+
|
|
255
|
+
## Confluence Configuration
|
|
256
|
+
CONFLUENCE_BASE_URL=https://your-org.atlassian.net/wiki
|
|
257
|
+
CONFLUENCE_SPACE_KEY=ENG
|
|
258
|
+
CONFLUENCE_ARCHITECTURE_PAGE_TITLE=MindForge Architecture
|
|
259
|
+
CONFLUENCE_ADR_PARENT_PAGE_TITLE=Architecture Decision Records
|
|
260
|
+
CONFLUENCE_PHASE_DOCS_PARENT_PAGE_TITLE=Sprint Documentation
|
|
261
|
+
# Auto-update on phase completion: true | false
|
|
262
|
+
CONFLUENCE_AUTO_PUBLISH=false
|
|
263
|
+
|
|
264
|
+
## Slack Configuration
|
|
265
|
+
SLACK_CHANNEL_ID=C01234ABCDE
|
|
266
|
+
SLACK_NOTIFY_ON=phase_complete,security_finding,approval_needed,blocker
|
|
267
|
+
SLACK_MENTION_ON_CRITICAL=@oncall
|
|
268
|
+
# Thread replies: group related notifications in a thread
|
|
269
|
+
SLACK_USE_THREADS=true
|
|
270
|
+
|
|
271
|
+
## GitHub Configuration
|
|
272
|
+
GITHUB_REPO=your-org/your-repo
|
|
273
|
+
GITHUB_DEFAULT_BRANCH=main
|
|
274
|
+
GITHUB_REQUIRED_REVIEWERS=2
|
|
275
|
+
GITHUB_DEFAULT_REVIEWERS=senior-engineer-1,senior-engineer-2
|
|
276
|
+
GITHUB_PR_TEMPLATE_PATH=.github/pull_request_template.md
|
|
277
|
+
GITHUB_DRAFT_BY_DEFAULT=false
|
|
278
|
+
|
|
279
|
+
## GitLab Configuration
|
|
280
|
+
# (fill in if using GitLab instead of GitHub)
|
|
281
|
+
GITLAB_PROJECT_ID=
|
|
282
|
+
GITLAB_DEFAULT_BRANCH=main
|
|
283
|
+
GITLAB_DEFAULT_REVIEWERS=
|
|
284
|
+
|
|
285
|
+
## Notification preferences
|
|
286
|
+
NOTIFY_PHASE_COMPLETE=true
|
|
287
|
+
NOTIFY_SECURITY_CRITICAL=true
|
|
288
|
+
NOTIFY_APPROVAL_NEEDED=true
|
|
289
|
+
NOTIFY_MILESTONE_COMPLETE=true
|
|
290
|
+
NOTIFY_BLOCKER_ADDED=true
|
|
291
|
+
```
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Commit:**
|
|
295
|
+
```bash
|
|
296
|
+
git add .mindforge/integrations/connection-manager.md \
|
|
297
|
+
.mindforge/org/integrations/INTEGRATIONS-CONFIG.md
|
|
298
|
+
git commit -m "feat(integrations): implement connection manager with credential safety model"
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## TASK 3 — Write Jira Integration
|
|
304
|
+
|
|
305
|
+
### `.mindforge/integrations/jira.md`
|
|
306
|
+
|
|
307
|
+
```markdown
|
|
308
|
+
# MindForge — Jira Integration
|
|
309
|
+
|
|
310
|
+
## Purpose
|
|
311
|
+
Bidirectional synchronisation between MindForge project phases/tasks and
|
|
312
|
+
Jira epics/stories. MindForge is the source of truth for technical planning.
|
|
313
|
+
Jira is the source of truth for business visibility and sprint tracking.
|
|
314
|
+
|
|
315
|
+
## Integration model
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
MindForge ←→ Jira
|
|
319
|
+
──────────────────────────────────────────
|
|
320
|
+
Project → Epic (auto-created)
|
|
321
|
+
Phase N → Epic (one per phase)
|
|
322
|
+
PLAN-N-M.md → Story (one per plan)
|
|
323
|
+
task_completed → Story status: Done
|
|
324
|
+
task_failed → Story status: Blocked + comment
|
|
325
|
+
security_finding → Bug with SECURITY label
|
|
326
|
+
Phase verification → Epic status: Ready for Review
|
|
327
|
+
UAT sign-off → Epic status: Done
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Jira API version
|
|
331
|
+
Use Jira REST API v3 (`/rest/api/3/`). This is the current version.
|
|
332
|
+
Never use v2 — it is being deprecated.
|
|
333
|
+
|
|
334
|
+
## Authentication
|
|
335
|
+
All API calls use HTTP Basic Auth with base64-encoded `email:api_token`.
|
|
336
|
+
The token is read from `JIRA_API_TOKEN` environment variable.
|
|
337
|
+
Never log or display the token value.
|
|
338
|
+
|
|
339
|
+
## Core operations
|
|
340
|
+
|
|
341
|
+
### Operation: Create Epic for Phase
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
# POST /rest/api/3/issue
|
|
345
|
+
# Creates a Jira Epic corresponding to a MindForge phase
|
|
346
|
+
|
|
347
|
+
REQUEST_BODY=$(cat << 'EOF'
|
|
348
|
+
{
|
|
349
|
+
"fields": {
|
|
350
|
+
"project": { "key": "${JIRA_PROJECT_KEY}" },
|
|
351
|
+
"summary": "Phase [N]: [phase description from ROADMAP.md]",
|
|
352
|
+
"description": {
|
|
353
|
+
"type": "doc",
|
|
354
|
+
"version": 1,
|
|
355
|
+
"content": [{
|
|
356
|
+
"type": "paragraph",
|
|
357
|
+
"content": [{
|
|
358
|
+
"type": "text",
|
|
359
|
+
"text": "MindForge Phase [N] — auto-created by MindForge.\nPhase goal: [phase goal]\nPlanning docs: .planning/phases/[N]/"
|
|
360
|
+
}]
|
|
361
|
+
}]
|
|
362
|
+
},
|
|
363
|
+
"issuetype": { "name": "Epic" },
|
|
364
|
+
"labels": ["mindforge-phase", "mindforge-phase-[N]"],
|
|
365
|
+
"customfield_10014": "Phase [N]: [description]"
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
EOF
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
curl -s -X POST \
|
|
372
|
+
-H "Authorization: Basic ${AUTH_HEADER}" \
|
|
373
|
+
-H "Content-Type: application/json" \
|
|
374
|
+
-d "${REQUEST_BODY}" \
|
|
375
|
+
"${JIRA_BASE_URL}/rest/api/3/issue"
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Store the returned epic key (e.g., `ENG-42`) in STATE.md under "Jira mappings":
|
|
379
|
+
```markdown
|
|
380
|
+
## Jira mappings
|
|
381
|
+
- Phase 1 → ENG-42 (Epic)
|
|
382
|
+
- Phase 2 → ENG-58 (Epic)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Operation: Create Story for Plan
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
# POST /rest/api/3/issue — create Story linked to Phase Epic
|
|
389
|
+
|
|
390
|
+
REQUEST_BODY=$(cat << 'EOF'
|
|
391
|
+
{
|
|
392
|
+
"fields": {
|
|
393
|
+
"project": { "key": "${JIRA_PROJECT_KEY}" },
|
|
394
|
+
"summary": "[task name from PLAN file <n> field]",
|
|
395
|
+
"description": {
|
|
396
|
+
"type": "doc",
|
|
397
|
+
"version": 1,
|
|
398
|
+
"content": [{
|
|
399
|
+
"type": "paragraph",
|
|
400
|
+
"content": [{ "type": "text", "text": "MindForge PLAN-[N]-[M]\nFiles: [files from plan]\n[action summary]" }]
|
|
401
|
+
}]
|
|
402
|
+
},
|
|
403
|
+
"issuetype": { "name": "Story" },
|
|
404
|
+
"parent": { "key": "${EPIC_KEY}" },
|
|
405
|
+
"labels": ["mindforge-plan-[N]-[M]"],
|
|
406
|
+
"priority": { "name": "Medium" }
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
EOF
|
|
410
|
+
)
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
### Operation: Update Story Status
|
|
414
|
+
|
|
415
|
+
Map MindForge task states to Jira transitions:
|
|
416
|
+
|
|
417
|
+
| MindForge event | Jira transition | Jira status |
|
|
418
|
+
|---|---|---|
|
|
419
|
+
| task_started | 11 (Start Progress) | In Progress |
|
|
420
|
+
| task_completed | 31 (Done) | Done |
|
|
421
|
+
| task_failed | 21 (Block) | Blocked |
|
|
422
|
+
| verify_passed | 31 (Done) | Done |
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# POST /rest/api/3/issue/{issueKey}/transitions
|
|
426
|
+
curl -s -X POST \
|
|
427
|
+
-H "Authorization: Basic ${AUTH_HEADER}" \
|
|
428
|
+
-H "Content-Type: application/json" \
|
|
429
|
+
-d '{"transition": {"id": "31"}}' \
|
|
430
|
+
"${JIRA_BASE_URL}/rest/api/3/issue/${STORY_KEY}/transitions"
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Operation: Create Security Bug
|
|
434
|
+
|
|
435
|
+
When a `security_finding` AUDIT entry has severity CRITICAL or HIGH:
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
REQUEST_BODY=$(cat << 'EOF'
|
|
439
|
+
{
|
|
440
|
+
"fields": {
|
|
441
|
+
"project": { "key": "${JIRA_PROJECT_KEY}" },
|
|
442
|
+
"summary": "[SEVERITY] Security: [finding description]",
|
|
443
|
+
"description": { ... owasp category, file, line, remediation ... },
|
|
444
|
+
"issuetype": { "name": "Bug" },
|
|
445
|
+
"labels": ["security", "mindforge-security", "[severity-lowercase]"],
|
|
446
|
+
"priority": { "name": "[Critical|High based on severity]" }
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
EOF
|
|
450
|
+
)
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
### Operation: Add comment to Epic/Story
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
# POST /rest/api/3/issue/{issueKey}/comment
|
|
457
|
+
REQUEST_BODY=$(cat << 'EOF'
|
|
458
|
+
{
|
|
459
|
+
"body": {
|
|
460
|
+
"type": "doc",
|
|
461
|
+
"version": 1,
|
|
462
|
+
"content": [{
|
|
463
|
+
"type": "paragraph",
|
|
464
|
+
"content": [{ "type": "text", "text": "[comment text]" }]
|
|
465
|
+
}]
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
EOF
|
|
469
|
+
)
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
## Sync state tracking
|
|
473
|
+
|
|
474
|
+
Maintain a sync state file at `.planning/jira-sync.json`:
|
|
475
|
+
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"schema_version": "1.0.0",
|
|
479
|
+
"last_sync": "ISO-8601",
|
|
480
|
+
"project_key": "ENG",
|
|
481
|
+
"phase_mappings": {
|
|
482
|
+
"1": { "epic_key": "ENG-42", "story_keys": { "01": "ENG-43", "02": "ENG-44" } },
|
|
483
|
+
"2": { "epic_key": "ENG-58", "story_keys": {} }
|
|
484
|
+
},
|
|
485
|
+
"security_bugs": [
|
|
486
|
+
{ "audit_id": "uuid", "issue_key": "ENG-91", "severity": "HIGH" }
|
|
487
|
+
],
|
|
488
|
+
"_warning": "Do not store credentials in this file."
|
|
489
|
+
}
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
## Conflict handling
|
|
493
|
+
|
|
494
|
+
If a Jira story is manually updated (status changed, comment added) since last sync:
|
|
495
|
+
Do NOT overwrite manual Jira changes with MindForge sync.
|
|
496
|
+
Only ADD information (new comments, new labels). Never destructively overwrite.
|
|
497
|
+
Log: `"sync_conflict_resolved": "manual_jira_changes_preserved"` in AUDIT.
|
|
498
|
+
|
|
499
|
+
## Rate limiting
|
|
500
|
+
Jira Cloud: 10 requests per second per token.
|
|
501
|
+
Between API calls: wait 200ms minimum.
|
|
502
|
+
On 429 response: wait `Retry-After` header value, then retry once.
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
### `.mindforge/integrations/confluence.md`
|
|
508
|
+
|
|
509
|
+
```markdown
|
|
510
|
+
# MindForge — Confluence Integration
|
|
511
|
+
|
|
512
|
+
## Purpose
|
|
513
|
+
Publish MindForge planning artifacts to Confluence so the entire organisation
|
|
514
|
+
has visibility into architecture decisions, phase documentation, and ADRs.
|
|
515
|
+
MindForge writes; Confluence displays. Team members do not need to run MindForge
|
|
516
|
+
to see what was decided and why.
|
|
517
|
+
|
|
518
|
+
## What gets published
|
|
519
|
+
| MindForge artifact | Confluence page | Update frequency |
|
|
520
|
+
|---|---|---|
|
|
521
|
+
| `.planning/ARCHITECTURE.md` | [Space]/MindForge Architecture | On demand / phase completion |
|
|
522
|
+
| `.planning/decisions/ADR-*.md` | [Space]/ADRs/[ADR title] | When ADR is created or status changes |
|
|
523
|
+
| `.planning/phases/[N]/VERIFICATION.md` | [Space]/Sprint Docs/Phase [N] Verification | On phase completion |
|
|
524
|
+
| `.planning/phases/[N]/UAT.md` | [Space]/Sprint Docs/Phase [N] UAT | On UAT sign-off |
|
|
525
|
+
| `CHANGELOG.md` | [Space]/Releases/Changelog | On milestone completion |
|
|
526
|
+
|
|
527
|
+
## Confluence API
|
|
528
|
+
Use Confluence REST API v2 (`/wiki/api/v2/`).
|
|
529
|
+
Authentication: same Basic Auth as Jira (Atlassian tokens are unified).
|
|
530
|
+
|
|
531
|
+
## Markdown to Confluence conversion
|
|
532
|
+
|
|
533
|
+
Confluence uses its own "storage format" (a dialect of XHTML).
|
|
534
|
+
Convert MindForge Markdown files before publishing:
|
|
535
|
+
|
|
536
|
+
### Conversion rules
|
|
537
|
+
```
|
|
538
|
+
# Heading → <h1>Heading</h1>
|
|
539
|
+
## Heading → <h2>Heading</h2>
|
|
540
|
+
**bold** → <strong>bold</strong>
|
|
541
|
+
`code` → <code>code</code>
|
|
542
|
+
| table | → <table><tbody><tr><td>table</td></tr></tbody></table>
|
|
543
|
+
```bash
|
|
544
|
+
code block
|
|
545
|
+
``` → <ac:structured-macro ac:name="code"><ac:plain-text-body><![CDATA[code block]]></ac:plain-text-body></ac:structured-macro>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
For complex documents: use the Confluence API's `representation: "wiki"` field
|
|
549
|
+
which accepts Confluence Wiki Markup (simpler to generate than storage format):
|
|
550
|
+
|
|
551
|
+
```
|
|
552
|
+
h1. Heading
|
|
553
|
+
h2. Heading
|
|
554
|
+
*bold*
|
|
555
|
+
{{inline code}}
|
|
556
|
+
{code:language=bash}
|
|
557
|
+
code block
|
|
558
|
+
{code}
|
|
559
|
+
| Table | Header |
|
|
560
|
+
| Cell 1 | Cell 2 |
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Core API operations
|
|
564
|
+
|
|
565
|
+
**Create a new page:**
|
|
566
|
+
```bash
|
|
567
|
+
curl -s -X POST \
|
|
568
|
+
-H "Authorization: Basic ${AUTH_HEADER}" \
|
|
569
|
+
-H "Content-Type: application/json" \
|
|
570
|
+
-d '{
|
|
571
|
+
"spaceId": "'${CONFLUENCE_SPACE_ID}'",
|
|
572
|
+
"status": "current",
|
|
573
|
+
"title": "[Page title]",
|
|
574
|
+
"parentId": "'${PARENT_PAGE_ID}'",
|
|
575
|
+
"body": {
|
|
576
|
+
"representation": "wiki",
|
|
577
|
+
"value": "[Confluence wiki markup content]"
|
|
578
|
+
}
|
|
579
|
+
}' \
|
|
580
|
+
"${CONFLUENCE_BASE_URL}/wiki/api/v2/pages"
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
**Update an existing page (must include current version number):**
|
|
584
|
+
```bash
|
|
585
|
+
# Step 1: Get current version
|
|
586
|
+
CURRENT_VERSION=$(curl -s \
|
|
587
|
+
-H "Authorization: Basic ${AUTH_HEADER}" \
|
|
588
|
+
"${CONFLUENCE_BASE_URL}/wiki/api/v2/pages/${PAGE_ID}" \
|
|
589
|
+
| python3 -c "import sys,json; print(json.load(sys.stdin)['version']['number'])")
|
|
590
|
+
|
|
591
|
+
# Step 2: Update with incremented version
|
|
592
|
+
curl -s -X PUT \
|
|
593
|
+
-H "Authorization: Basic ${AUTH_HEADER}" \
|
|
594
|
+
-H "Content-Type: application/json" \
|
|
595
|
+
-d '{
|
|
596
|
+
"id": "'${PAGE_ID}'",
|
|
597
|
+
"status": "current",
|
|
598
|
+
"title": "[Page title]",
|
|
599
|
+
"body": { "representation": "wiki", "value": "[content]" },
|
|
600
|
+
"version": { "number": '$(($CURRENT_VERSION + 1))' }
|
|
601
|
+
}' \
|
|
602
|
+
"${CONFLUENCE_BASE_URL}/wiki/api/v2/pages/${PAGE_ID}"
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## Page ID caching
|
|
606
|
+
|
|
607
|
+
Store published page IDs in `.planning/confluence-sync.json`:
|
|
608
|
+
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"schema_version": "1.0.0",
|
|
612
|
+
"last_sync": "ISO-8601",
|
|
613
|
+
"space_id": "~12345678",
|
|
614
|
+
"pages": {
|
|
615
|
+
"architecture": { "page_id": "123456", "last_updated": "ISO-8601", "version": 3 },
|
|
616
|
+
"adr-001": { "page_id": "234567", "last_updated": "ISO-8601", "version": 1 },
|
|
617
|
+
"adr-002": { "page_id": "234568", "last_updated": "ISO-8601", "version": 2 },
|
|
618
|
+
"phase-1-verification": { "page_id": "345678", "last_updated": "ISO-8601", "version": 1 }
|
|
619
|
+
},
|
|
620
|
+
"_warning": "Do not store credentials in this file."
|
|
621
|
+
}
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## Idempotency rule
|
|
625
|
+
Publishing is idempotent. Running sync twice produces identical pages.
|
|
626
|
+
Detect existing pages via `confluence-sync.json` before creating new ones.
|
|
627
|
+
Never create duplicate pages — always update if a page already exists.
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
### `.mindforge/integrations/slack.md`
|
|
633
|
+
|
|
634
|
+
```markdown
|
|
635
|
+
# MindForge — Slack Integration
|
|
636
|
+
|
|
637
|
+
## Purpose
|
|
638
|
+
Send structured, actionable notifications to the team's Slack channel
|
|
639
|
+
at the right moments: phase completions, security findings, approval requests,
|
|
640
|
+
and blockers. Not every event — only events that require human attention.
|
|
641
|
+
|
|
642
|
+
## Notification philosophy
|
|
643
|
+
- **Signal over noise:** only notify when human action is needed or when a
|
|
644
|
+
significant milestone has been reached. Never notify on routine progress.
|
|
645
|
+
- **Actionable:** every notification should make the reader's next step obvious.
|
|
646
|
+
- **Threadable:** group related notifications in Slack threads to keep the channel clean.
|
|
647
|
+
|
|
648
|
+
## Events that trigger notifications
|
|
649
|
+
|
|
650
|
+
| Event | Channel notification | Who is mentioned |
|
|
651
|
+
|---|---|---|
|
|
652
|
+
| Phase complete | ✅ Yes | Phase owner (from STATE.md) |
|
|
653
|
+
| Security CRITICAL finding | ✅ Yes | Security team / `@oncall` |
|
|
654
|
+
| Security HIGH finding | ✅ Yes | Tech lead |
|
|
655
|
+
| Approval needed (Tier 2/3) | ✅ Yes | Assigned approver |
|
|
656
|
+
| Blocker added to STATE.md | ✅ Yes | Phase owner |
|
|
657
|
+
| Milestone complete | ✅ Yes | Entire team channel |
|
|
658
|
+
| Task completed | ❌ No | — (too noisy) |
|
|
659
|
+
| UAT sign-off | ✅ Yes | Stakeholder / PM |
|
|
660
|
+
| Build/test failure | ✅ Yes | Phase owner |
|
|
661
|
+
|
|
662
|
+
## Slack Block Kit message templates
|
|
663
|
+
|
|
664
|
+
### Phase completion notification
|
|
665
|
+
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"channel": "${SLACK_CHANNEL_ID}",
|
|
669
|
+
"blocks": [
|
|
670
|
+
{
|
|
671
|
+
"type": "header",
|
|
672
|
+
"text": { "type": "plain_text", "text": "✅ Phase [N] Complete" }
|
|
673
|
+
},
|
|
674
|
+
{
|
|
675
|
+
"type": "section",
|
|
676
|
+
"fields": [
|
|
677
|
+
{ "type": "mrkdwn", "text": "*Project:*\n[project name]" },
|
|
678
|
+
{ "type": "mrkdwn", "text": "*Phase:*\n[N] — [phase description]" },
|
|
679
|
+
{ "type": "mrkdwn", "text": "*Tasks completed:*\n[X] / [X]" },
|
|
680
|
+
{ "type": "mrkdwn", "text": "*Requirements met:*\n[X] / [X]" }
|
|
681
|
+
]
|
|
682
|
+
},
|
|
683
|
+
{
|
|
684
|
+
"type": "section",
|
|
685
|
+
"text": { "type": "mrkdwn", "text": "*Commits:* [X] | *Tests:* All passing ✅" }
|
|
686
|
+
},
|
|
687
|
+
{
|
|
688
|
+
"type": "actions",
|
|
689
|
+
"elements": [
|
|
690
|
+
{
|
|
691
|
+
"type": "button",
|
|
692
|
+
"text": { "type": "plain_text", "text": "View UAT" },
|
|
693
|
+
"url": "[link to UAT.md in repo]"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
"type": "button",
|
|
697
|
+
"text": { "type": "plain_text", "text": "View in Jira" },
|
|
698
|
+
"url": "[Jira epic URL]"
|
|
699
|
+
}
|
|
700
|
+
]
|
|
701
|
+
}
|
|
702
|
+
]
|
|
703
|
+
}
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
### Security critical finding notification
|
|
707
|
+
|
|
708
|
+
```json
|
|
709
|
+
{
|
|
710
|
+
"channel": "${SLACK_CHANNEL_ID}",
|
|
711
|
+
"blocks": [
|
|
712
|
+
{
|
|
713
|
+
"type": "header",
|
|
714
|
+
"text": { "type": "plain_text", "text": "🔴 Critical Security Finding" }
|
|
715
|
+
},
|
|
716
|
+
{
|
|
717
|
+
"type": "section",
|
|
718
|
+
"text": {
|
|
719
|
+
"type": "mrkdwn",
|
|
720
|
+
"text": "<!channel> A critical security issue was found during Phase [N] execution.\n*Severity:* CRITICAL\n*Category:* [OWASP category]\n*Finding:* [one-line description]\n*File:* `[file:line]`"
|
|
721
|
+
}
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"type": "section",
|
|
725
|
+
"text": {
|
|
726
|
+
"type": "mrkdwn",
|
|
727
|
+
"text": "*Immediate action required:* Run `/mindforge:security-scan` and review findings before any deployment."
|
|
728
|
+
}
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"type": "context",
|
|
732
|
+
"elements": [{ "type": "mrkdwn", "text": "Report: `.planning/phases/[N]/SECURITY-REVIEW-[N].md`" }]
|
|
733
|
+
}
|
|
734
|
+
]
|
|
735
|
+
}
|
|
736
|
+
```
|
|
737
|
+
|
|
738
|
+
### Approval request notification
|
|
739
|
+
|
|
740
|
+
```json
|
|
741
|
+
{
|
|
742
|
+
"channel": "${SLACK_CHANNEL_ID}",
|
|
743
|
+
"blocks": [
|
|
744
|
+
{
|
|
745
|
+
"type": "header",
|
|
746
|
+
"text": { "type": "plain_text", "text": "⏳ Approval Required" }
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"type": "section",
|
|
750
|
+
"fields": [
|
|
751
|
+
{ "type": "mrkdwn", "text": "*Type:*\n[Tier 2: Feature / Tier 3: Compliance]" },
|
|
752
|
+
{ "type": "mrkdwn", "text": "*Requested by:*\n@[requester]" },
|
|
753
|
+
{ "type": "mrkdwn", "text": "*Approver:*\n@[assigned approver]" },
|
|
754
|
+
{ "type": "mrkdwn", "text": "*Phase/Plan:*\nPhase [N], Plan [M]" }
|
|
755
|
+
]
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
"type": "section",
|
|
759
|
+
"text": { "type": "mrkdwn", "text": "*Change:* [description]\n*Risk:* [risk assessment]\n*Rollback:* [rollback plan if available]" }
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"type": "actions",
|
|
763
|
+
"elements": [
|
|
764
|
+
{
|
|
765
|
+
"type": "button",
|
|
766
|
+
"style": "primary",
|
|
767
|
+
"text": { "type": "plain_text", "text": "✅ Approve" },
|
|
768
|
+
"value": "approve:[approval-id]"
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
"type": "button",
|
|
772
|
+
"style": "danger",
|
|
773
|
+
"text": { "type": "plain_text", "text": "❌ Reject" },
|
|
774
|
+
"value": "reject:[approval-id]"
|
|
775
|
+
},
|
|
776
|
+
{
|
|
777
|
+
"type": "button",
|
|
778
|
+
"text": { "type": "plain_text", "text": "Review changes" },
|
|
779
|
+
"url": "[link to diff or plan]"
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
}
|
|
783
|
+
]
|
|
784
|
+
}
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
## Sending notifications
|
|
788
|
+
|
|
789
|
+
```bash
|
|
790
|
+
curl -s -X POST \
|
|
791
|
+
-H "Authorization: Bearer ${SLACK_BOT_TOKEN}" \
|
|
792
|
+
-H "Content-Type: application/json" \
|
|
793
|
+
-d "${MESSAGE_JSON}" \
|
|
794
|
+
https://slack.com/api/chat.postMessage
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
## Thread management
|
|
798
|
+
|
|
799
|
+
When `SLACK_USE_THREADS=true`:
|
|
800
|
+
1. The first notification for a phase creates a thread (record the `ts` value)
|
|
801
|
+
2. All subsequent notifications for the same phase reply to that thread
|
|
802
|
+
3. Store thread `ts` values in `.planning/slack-threads.json`:
|
|
803
|
+
|
|
804
|
+
```json
|
|
805
|
+
{
|
|
806
|
+
"schema_version": "1.0.0",
|
|
807
|
+
"threads": {
|
|
808
|
+
"phase-1": "1234567890.123456",
|
|
809
|
+
"phase-2": "1234567891.234567",
|
|
810
|
+
"milestone-v1": "1234567892.345678"
|
|
811
|
+
},
|
|
812
|
+
"_warning": "Do not store credentials in this file."
|
|
813
|
+
}
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
## Graceful degradation
|
|
817
|
+
If Slack is unconfigured (`SLACK_BOT_TOKEN` not set):
|
|
818
|
+
- Skip all notifications silently
|
|
819
|
+
- Log to AUDIT: `{ "event": "notification_skipped", "reason": "slack_unconfigured" }`
|
|
820
|
+
- Never fail a phase execution because Slack is unavailable
|
|
821
|
+
```
|
|
822
|
+
|
|
823
|
+
**Commit:**
|
|
824
|
+
```bash
|
|
825
|
+
git add .mindforge/integrations/
|
|
826
|
+
git commit -m "feat(integrations): implement Jira, Confluence, Slack integration specs"
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
---
|
|
830
|
+
|
|
831
|
+
## TASK 4 — Write GitHub/GitLab Enhanced Ship Integration
|
|
832
|
+
|
|
833
|
+
### `.mindforge/integrations/github.md`
|
|
834
|
+
|
|
835
|
+
```markdown
|
|
836
|
+
# MindForge — GitHub Integration
|
|
837
|
+
|
|
838
|
+
## Purpose
|
|
839
|
+
Enhance the `/mindforge:ship` command with professional, standards-compliant
|
|
840
|
+
pull requests: structured templates, automatic reviewer assignment, branch
|
|
841
|
+
protection compliance checks, and release tag management.
|
|
842
|
+
|
|
843
|
+
## GitHub REST API version
|
|
844
|
+
Use GitHub REST API v4 (GraphQL) for complex queries, REST v3 for mutations.
|
|
845
|
+
Base URL: `https://api.github.com`
|
|
846
|
+
Authentication: `Authorization: Bearer ${GITHUB_TOKEN}`
|
|
847
|
+
|
|
848
|
+
## Enhanced PR creation
|
|
849
|
+
|
|
850
|
+
### Pre-flight checks before creating a PR
|
|
851
|
+
|
|
852
|
+
```bash
|
|
853
|
+
# 1. Verify branch protection compliance
|
|
854
|
+
# Check if the source branch can be merged (no merge conflicts, required checks pass)
|
|
855
|
+
curl -s \
|
|
856
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
857
|
+
-H "Accept: application/vnd.github.v3+json" \
|
|
858
|
+
"https://api.github.com/repos/${GITHUB_REPO}/branches/${CURRENT_BRANCH}/protection"
|
|
859
|
+
|
|
860
|
+
# 2. Check if required status checks are passing
|
|
861
|
+
curl -s \
|
|
862
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
863
|
+
"https://api.github.com/repos/${GITHUB_REPO}/commits/${CURRENT_SHA}/check-runs"
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### PR creation payload
|
|
867
|
+
|
|
868
|
+
```bash
|
|
869
|
+
PR_BODY=$(cat .github/pull_request_template.md 2>/dev/null || echo "[no template found — using generated body]")
|
|
870
|
+
|
|
871
|
+
REQUEST_BODY=$(cat << EOF
|
|
872
|
+
{
|
|
873
|
+
"title": "[Phase N]: [phase description]",
|
|
874
|
+
"body": "${PR_BODY}",
|
|
875
|
+
"head": "${CURRENT_BRANCH}",
|
|
876
|
+
"base": "${GITHUB_DEFAULT_BRANCH}",
|
|
877
|
+
"draft": ${GITHUB_DRAFT_BY_DEFAULT},
|
|
878
|
+
"maintainer_can_modify": true
|
|
879
|
+
}
|
|
880
|
+
EOF
|
|
881
|
+
)
|
|
882
|
+
|
|
883
|
+
PR_RESPONSE=$(curl -s -X POST \
|
|
884
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
885
|
+
-H "Content-Type: application/json" \
|
|
886
|
+
-d "${REQUEST_BODY}" \
|
|
887
|
+
"https://api.github.com/repos/${GITHUB_REPO}/pulls")
|
|
888
|
+
|
|
889
|
+
PR_NUMBER=$(echo "${PR_RESPONSE}" | python3 -c "import sys,json; print(json.load(sys.stdin)['number'])")
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
### Auto-assign reviewers
|
|
893
|
+
|
|
894
|
+
```bash
|
|
895
|
+
curl -s -X POST \
|
|
896
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
897
|
+
-H "Content-Type: application/json" \
|
|
898
|
+
-d '{
|
|
899
|
+
"reviewers": ['$(echo ${GITHUB_DEFAULT_REVIEWERS} | tr ',' '\n' | python3 -c "import sys; print(','.join(['\"'+l.strip()+'\"' for l in sys.stdin]))' ]
|
|
900
|
+
}' \
|
|
901
|
+
"https://api.github.com/repos/${GITHUB_REPO}/pulls/${PR_NUMBER}/requested_reviewers"
|
|
902
|
+
```
|
|
903
|
+
|
|
904
|
+
### Add PR labels
|
|
905
|
+
|
|
906
|
+
```bash
|
|
907
|
+
curl -s -X POST \
|
|
908
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
909
|
+
-H "Content-Type: application/json" \
|
|
910
|
+
-d '{"labels": ["mindforge", "phase-[N]", "auto-generated"]}' \
|
|
911
|
+
"https://api.github.com/repos/${GITHUB_REPO}/issues/${PR_NUMBER}/labels"
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
### Link Jira tickets in PR body
|
|
915
|
+
|
|
916
|
+
If Jira integration is active, include ticket references in the PR body:
|
|
917
|
+
```
|
|
918
|
+
## Related issues
|
|
919
|
+
- Phase Epic: [ENG-42](https://your-org.atlassian.net/browse/ENG-42)
|
|
920
|
+
- Stories: [ENG-43](…), [ENG-44](…), [ENG-45](…)
|
|
921
|
+
```
|
|
922
|
+
|
|
923
|
+
## PR template
|
|
924
|
+
|
|
925
|
+
Write `.github/pull_request_template.md` if it doesn't exist:
|
|
926
|
+
|
|
927
|
+
```markdown
|
|
928
|
+
## Summary
|
|
929
|
+
<!-- 2-3 sentences: what this PR delivers -->
|
|
930
|
+
|
|
931
|
+
## MindForge Phase
|
|
932
|
+
- **Phase:** [N] — [description]
|
|
933
|
+
- **Branch:** [branch name]
|
|
934
|
+
- **Milestone:** [milestone name if applicable]
|
|
935
|
+
|
|
936
|
+
## Changes
|
|
937
|
+
<!-- Auto-populated by MindForge from SUMMARY files -->
|
|
938
|
+
|
|
939
|
+
## Requirements delivered
|
|
940
|
+
| ID | Requirement | Verified |
|
|
941
|
+
|---|---|---|
|
|
942
|
+
| FR-XX | ... | ✅ |
|
|
943
|
+
|
|
944
|
+
## Testing
|
|
945
|
+
- [ ] Unit tests pass (see VERIFICATION.md)
|
|
946
|
+
- [ ] Integration tests pass
|
|
947
|
+
- [ ] Human UAT completed (see UAT.md)
|
|
948
|
+
- [ ] Performance tested (if applicable)
|
|
949
|
+
- [ ] Accessibility tested (if applicable)
|
|
950
|
+
|
|
951
|
+
## Security
|
|
952
|
+
- [ ] Security scan completed (see SECURITY-REVIEW-N.md)
|
|
953
|
+
- [ ] No hardcoded credentials in diff
|
|
954
|
+
- [ ] Dependencies scanned for CVEs
|
|
955
|
+
- [ ] No CRITICAL or HIGH security findings
|
|
956
|
+
|
|
957
|
+
## Documentation
|
|
958
|
+
- [ ] CHANGELOG.md updated
|
|
959
|
+
- [ ] Architecture doc updated (if applicable)
|
|
960
|
+
- [ ] ADRs written for new decisions
|
|
961
|
+
- [ ] Confluence pages published (if integration active)
|
|
962
|
+
|
|
963
|
+
## Reviewer notes
|
|
964
|
+
<!-- Anything the reviewer specifically needs to know or check -->
|
|
965
|
+
```
|
|
966
|
+
|
|
967
|
+
## Release tag creation
|
|
968
|
+
|
|
969
|
+
After a PR is merged:
|
|
970
|
+
|
|
971
|
+
```bash
|
|
972
|
+
# Create annotated release tag
|
|
973
|
+
curl -s -X POST \
|
|
974
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
975
|
+
-H "Content-Type: application/json" \
|
|
976
|
+
-d '{
|
|
977
|
+
"tag": "v'${VERSION}'",
|
|
978
|
+
"message": "Release v'${VERSION}' — Phase [N]: [description]",
|
|
979
|
+
"object": "'${MERGE_COMMIT_SHA}'",
|
|
980
|
+
"type": "commit",
|
|
981
|
+
"tagger": {
|
|
982
|
+
"name": "MindForge",
|
|
983
|
+
"email": "mindforge@your-org.com",
|
|
984
|
+
"date": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'"
|
|
985
|
+
}
|
|
986
|
+
}' \
|
|
987
|
+
"https://api.github.com/repos/${GITHUB_REPO}/git/tags"
|
|
988
|
+
```
|
|
989
|
+
|
|
990
|
+
## Branch naming convention
|
|
991
|
+
|
|
992
|
+
MindForge branches follow this convention:
|
|
993
|
+
```
|
|
994
|
+
feat/mindforge-phase-[N]-[slug]
|
|
995
|
+
fix/mindforge-hotfix-[description]
|
|
996
|
+
chore/mindforge-maintenance-[description]
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
The branch is created automatically when `/mindforge:execute-phase` starts
|
|
1000
|
+
(if `git.branching_strategy = "phase"` in config).
|
|
1001
|
+
```
|
|
1002
|
+
|
|
1003
|
+
---
|
|
1004
|
+
|
|
1005
|
+
### `.mindforge/integrations/gitlab.md`
|
|
1006
|
+
|
|
1007
|
+
```markdown
|
|
1008
|
+
# MindForge — GitLab Integration
|
|
1009
|
+
|
|
1010
|
+
## Purpose
|
|
1011
|
+
Mirror of the GitHub integration for teams using GitLab.
|
|
1012
|
+
GitLab MR (Merge Request) workflow equivalent.
|
|
1013
|
+
|
|
1014
|
+
## GitLab REST API
|
|
1015
|
+
Base URL: `https://gitlab.com/api/v4` (or self-hosted equivalent)
|
|
1016
|
+
Authentication: `Authorization: Bearer ${GITLAB_TOKEN}`
|
|
1017
|
+
Project: identified by `GITLAB_PROJECT_ID` (numeric)
|
|
1018
|
+
|
|
1019
|
+
## Core operations
|
|
1020
|
+
|
|
1021
|
+
### Create Merge Request
|
|
1022
|
+
|
|
1023
|
+
```bash
|
|
1024
|
+
curl -s -X POST \
|
|
1025
|
+
-H "Authorization: Bearer ${GITLAB_TOKEN}" \
|
|
1026
|
+
-H "Content-Type: application/json" \
|
|
1027
|
+
-d '{
|
|
1028
|
+
"source_branch": "'${CURRENT_BRANCH}'",
|
|
1029
|
+
"target_branch": "'${GITLAB_DEFAULT_BRANCH}'",
|
|
1030
|
+
"title": "[Phase N]: [description]",
|
|
1031
|
+
"description": "'${MR_BODY}'",
|
|
1032
|
+
"reviewer_ids": [${REVIEWER_IDS}],
|
|
1033
|
+
"labels": "mindforge,phase-[N]",
|
|
1034
|
+
"remove_source_branch": true,
|
|
1035
|
+
"squash": false
|
|
1036
|
+
}' \
|
|
1037
|
+
"https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/merge_requests"
|
|
1038
|
+
```
|
|
1039
|
+
|
|
1040
|
+
### Create release tag
|
|
1041
|
+
|
|
1042
|
+
```bash
|
|
1043
|
+
curl -s -X POST \
|
|
1044
|
+
-H "Authorization: Bearer ${GITLAB_TOKEN}" \
|
|
1045
|
+
-H "Content-Type: application/json" \
|
|
1046
|
+
-d '{
|
|
1047
|
+
"name": "v'${VERSION}'",
|
|
1048
|
+
"tag_name": "v'${VERSION}'",
|
|
1049
|
+
"ref": "'${DEFAULT_BRANCH}'",
|
|
1050
|
+
"description": "'${RELEASE_NOTES}'"
|
|
1051
|
+
}' \
|
|
1052
|
+
"https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/releases"
|
|
1053
|
+
```
|
|
1054
|
+
|
|
1055
|
+
## GitLab vs GitHub differences
|
|
1056
|
+
- GitLab uses "Merge Requests" (MR) not "Pull Requests" (PR)
|
|
1057
|
+
- GitLab reviewer IDs are numeric — look them up by username before creating MR
|
|
1058
|
+
- GitLab self-hosted: replace `https://gitlab.com` with your instance URL
|
|
1059
|
+
- GitLab CI: status checks are "pipelines" — check pipeline status, not check-runs
|
|
1060
|
+
```
|
|
1061
|
+
|
|
1062
|
+
**Commit:**
|
|
1063
|
+
```bash
|
|
1064
|
+
git add .mindforge/integrations/github.md .mindforge/integrations/gitlab.md
|
|
1065
|
+
git commit -m "feat(integrations): implement GitHub and GitLab enhanced ship specs"
|
|
1066
|
+
```
|
|
1067
|
+
|
|
1068
|
+
---
|
|
1069
|
+
|
|
1070
|
+
## TASK 5 — Write the Governance Layer
|
|
1071
|
+
|
|
1072
|
+
The governance layer is MindForge's enterprise differentiator.
|
|
1073
|
+
It adds approval workflows, compliance gates, and change classification.
|
|
1074
|
+
|
|
1075
|
+
### `.mindforge/governance/change-classifier.md`
|
|
1076
|
+
|
|
1077
|
+
```markdown
|
|
1078
|
+
# MindForge Governance — Change Classifier
|
|
1079
|
+
|
|
1080
|
+
## Purpose
|
|
1081
|
+
Classify every MindForge code change into one of three approval tiers before
|
|
1082
|
+
execution. The tier determines the approval workflow required.
|
|
1083
|
+
|
|
1084
|
+
## Classification tiers
|
|
1085
|
+
|
|
1086
|
+
### Tier 1 — Auto-approved (no human approval needed)
|
|
1087
|
+
Changes that are low-risk, reversible, and covered by automated testing.
|
|
1088
|
+
|
|
1089
|
+
**Classification criteria:**
|
|
1090
|
+
- Bug fixes in non-security-critical paths
|
|
1091
|
+
- Documentation updates
|
|
1092
|
+
- Test additions or improvements
|
|
1093
|
+
- Dependency updates (PATCH versions — no new capabilities)
|
|
1094
|
+
- Refactoring with no behaviour change (verified by tests)
|
|
1095
|
+
- Configuration changes to non-sensitive values
|
|
1096
|
+
|
|
1097
|
+
**Verification:** Automated quality gates must pass:
|
|
1098
|
+
- Test suite: all passing
|
|
1099
|
+
- Linting: zero errors
|
|
1100
|
+
- Type checking: zero errors
|
|
1101
|
+
- Security scan: no new findings
|
|
1102
|
+
|
|
1103
|
+
**Approval SLA:** None — auto-approved when all gates pass.
|
|
1104
|
+
|
|
1105
|
+
---
|
|
1106
|
+
|
|
1107
|
+
### Tier 2 — Peer Review Required
|
|
1108
|
+
Changes that introduce new behaviour, touch dependencies, or affect multiple
|
|
1109
|
+
subsystems. Requires one senior engineer approval.
|
|
1110
|
+
|
|
1111
|
+
**Classification criteria — classify as Tier 2 if ANY of these are true:**
|
|
1112
|
+
- New feature implementation (any `feat:` commit)
|
|
1113
|
+
- Dependency additions (not just updates)
|
|
1114
|
+
- MINOR or MAJOR dependency version updates
|
|
1115
|
+
- Database schema changes (new tables, new columns, index changes)
|
|
1116
|
+
- API surface changes (new endpoints, changed request/response schemas)
|
|
1117
|
+
- Configuration changes to sensitive-but-not-critical values
|
|
1118
|
+
- Infrastructure changes (Dockerfile, docker-compose, CI/CD pipelines)
|
|
1119
|
+
- Changes affecting > 10 files or > 300 lines
|
|
1120
|
+
- New environment variables being added
|
|
1121
|
+
|
|
1122
|
+
**Verification:** Tier 1 gates + code review approval from at least one
|
|
1123
|
+
designated reviewer (`GITHUB_DEFAULT_REVIEWERS` from INTEGRATIONS-CONFIG.md).
|
|
1124
|
+
|
|
1125
|
+
**Approval SLA:** Target 24 hours. Escalate if no response after 48 hours.
|
|
1126
|
+
|
|
1127
|
+
---
|
|
1128
|
+
|
|
1129
|
+
### Tier 3 — Compliance Review Required
|
|
1130
|
+
High-risk changes with regulatory, security, or financial implications.
|
|
1131
|
+
Requires designated approver (security officer, compliance officer, or CTO).
|
|
1132
|
+
|
|
1133
|
+
**Classification criteria — classify as Tier 3 if ANY of these are true:**
|
|
1134
|
+
- Authentication or authorisation logic (login, logout, token handling, OAuth)
|
|
1135
|
+
- Password handling, credential storage, or encryption key management
|
|
1136
|
+
- Payment processing, financial data access, or billing logic
|
|
1137
|
+
- Personal data (PII, PHI) access patterns
|
|
1138
|
+
- Data deletion or anonymisation workflows
|
|
1139
|
+
- User role and permission models
|
|
1140
|
+
- Cross-border data transfer configuration
|
|
1141
|
+
- External security auditor findings being remediated
|
|
1142
|
+
- Changes to security policies, rate limiting, or CORS configuration
|
|
1143
|
+
|
|
1144
|
+
**Verification:** Tier 2 gates + explicit written approval from the designated
|
|
1145
|
+
compliance approver with a documented risk assessment.
|
|
1146
|
+
|
|
1147
|
+
**Approval SLA:** Target 4 hours for P0/P1 related changes. 48 hours standard.
|
|
1148
|
+
|
|
1149
|
+
---
|
|
1150
|
+
|
|
1151
|
+
## Automatic classification protocol
|
|
1152
|
+
|
|
1153
|
+
When the change classifier runs (before any Tier 2/3 commit or PR):
|
|
1154
|
+
|
|
1155
|
+
### Step 1 — Read the diff
|
|
1156
|
+
```bash
|
|
1157
|
+
git diff HEAD --name-only --diff-filter=ACMR
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
### Step 2 — Apply Tier 3 rules first (highest priority)
|
|
1161
|
+
Scan diff for Tier 3 patterns. Check:
|
|
1162
|
+
- File paths containing: `auth/`, `security/`, `payment/`, `billing/`, `privacy/`
|
|
1163
|
+
- File names: `session.ts`, `login.ts`, `token.ts`, `password.ts`, `credentials.ts`
|
|
1164
|
+
- Code patterns: `bcrypt`, `argon2`, `jwt.sign`, `jwt.verify`, `stripe.`, `twilio.`
|
|
1165
|
+
- AUDIT entries: any `security_finding` of CRITICAL or HIGH
|
|
1166
|
+
If ANY Tier 3 pattern matches: classify as Tier 3. Do not continue to Tier 2 check.
|
|
1167
|
+
|
|
1168
|
+
### Step 3 — Apply Tier 2 rules
|
|
1169
|
+
If not Tier 3, scan for Tier 2 patterns. Check:
|
|
1170
|
+
- Any `feat:` commit in the diff's commits
|
|
1171
|
+
- `package.json` changes (dependencies added or changed)
|
|
1172
|
+
- Database migration files present
|
|
1173
|
+
- New `.md` files added to `src/api/` or `routes/`
|
|
1174
|
+
- More than 10 files changed
|
|
1175
|
+
If ANY Tier 2 pattern matches: classify as Tier 2.
|
|
1176
|
+
|
|
1177
|
+
### Step 4 — Default to Tier 1
|
|
1178
|
+
If neither Tier 3 nor Tier 2 patterns match: Tier 1 auto-approved.
|
|
1179
|
+
|
|
1180
|
+
### Step 5 — Write classification to AUDIT
|
|
1181
|
+
```json
|
|
1182
|
+
{
|
|
1183
|
+
"event": "change_classified",
|
|
1184
|
+
"tier": 1,
|
|
1185
|
+
"classification_reason": "no Tier 2 or Tier 3 patterns found",
|
|
1186
|
+
"files_checked": [N],
|
|
1187
|
+
"patterns_matched": []
|
|
1188
|
+
}
|
|
1189
|
+
```
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
---
|
|
1193
|
+
|
|
1194
|
+
### `.mindforge/governance/approval-workflow.md`
|
|
1195
|
+
|
|
1196
|
+
```markdown
|
|
1197
|
+
# MindForge Governance — Approval Workflow
|
|
1198
|
+
|
|
1199
|
+
## Purpose
|
|
1200
|
+
Define the exact process for requesting, tracking, and recording approvals
|
|
1201
|
+
for Tier 2 and Tier 3 changes.
|
|
1202
|
+
|
|
1203
|
+
## Approval request lifecycle
|
|
1204
|
+
|
|
1205
|
+
```
|
|
1206
|
+
PENDING → APPROVED ✅
|
|
1207
|
+
→ REJECTED ❌
|
|
1208
|
+
→ EXPIRED (48 hours with no response) → escalate
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
## Approval request format
|
|
1212
|
+
|
|
1213
|
+
Write to `.planning/approvals/APPROVAL-[uuid].json`:
|
|
1214
|
+
|
|
1215
|
+
```json
|
|
1216
|
+
{
|
|
1217
|
+
"schema_version": "1.0.0",
|
|
1218
|
+
"id": "uuid-v4",
|
|
1219
|
+
"tier": 2,
|
|
1220
|
+
"status": "pending",
|
|
1221
|
+
"requested_at": "ISO-8601",
|
|
1222
|
+
"expires_at": "ISO-8601 (+48h for Tier 2, +4h for Tier 3 P0)",
|
|
1223
|
+
"requester": "mindforge-orchestrator",
|
|
1224
|
+
"approver": "designated-reviewer-from-config",
|
|
1225
|
+
"phase": 3,
|
|
1226
|
+
"plan": "02",
|
|
1227
|
+
"change_description": "Add user role management with admin/editor/viewer roles",
|
|
1228
|
+
"change_classification_reason": "New permission model — Tier 3: authorisation logic",
|
|
1229
|
+
"files_changed": ["src/auth/roles.ts", "src/middleware/rbac.ts"],
|
|
1230
|
+
"risk_assessment": {
|
|
1231
|
+
"risk_level": "medium",
|
|
1232
|
+
"rollback_plan": "Revert commit sha:abc1234 — no migration rollback needed",
|
|
1233
|
+
"blast_radius": "All authenticated users — role check on every request"
|
|
1234
|
+
},
|
|
1235
|
+
"jira_ticket": "ENG-67",
|
|
1236
|
+
"slack_notification_ts": "1234567890.123456",
|
|
1237
|
+
"resolution": null,
|
|
1238
|
+
"resolved_at": null,
|
|
1239
|
+
"resolver_notes": null,
|
|
1240
|
+
"_warning": "Do not store credentials in this file."
|
|
1241
|
+
}
|
|
1242
|
+
```
|
|
1243
|
+
|
|
1244
|
+
## Requesting approval
|
|
1245
|
+
|
|
1246
|
+
When the change classifier returns Tier 2 or Tier 3:
|
|
1247
|
+
|
|
1248
|
+
### Step 1 — Create approval request file
|
|
1249
|
+
Generate a UUID. Write the approval request JSON.
|
|
1250
|
+
Create directory `.planning/approvals/` if it doesn't exist.
|
|
1251
|
+
|
|
1252
|
+
### Step 2 — Send Slack notification (if configured)
|
|
1253
|
+
Use the approval request Slack template from `slack.md`.
|
|
1254
|
+
Store the Slack message `ts` value in the approval request file.
|
|
1255
|
+
|
|
1256
|
+
### Step 3 — Create Jira ticket (if configured, Tier 3 only)
|
|
1257
|
+
For Tier 3 changes: create a Jira ticket for the approval workflow.
|
|
1258
|
+
Link it to the phase epic.
|
|
1259
|
+
|
|
1260
|
+
### Step 4 — Block execution until resolved
|
|
1261
|
+
Do not proceed with any more execution until this approval is APPROVED.
|
|
1262
|
+
Poll for approval status every 5 minutes:
|
|
1263
|
+
```
|
|
1264
|
+
Waiting for [Tier 2/3] approval...
|
|
1265
|
+
Requested : [timestamp]
|
|
1266
|
+
Approver : [name]
|
|
1267
|
+
Expires : [timestamp]
|
|
1268
|
+
Status : PENDING
|
|
1269
|
+
|
|
1270
|
+
Run /mindforge:approve [approval-id] to approve, or check Slack.
|
|
1271
|
+
```
|
|
1272
|
+
|
|
1273
|
+
### Step 5 — On approval
|
|
1274
|
+
1. Update approval JSON: `"status": "approved"`, `"resolved_at": ISO-8601`
|
|
1275
|
+
2. Write AUDIT entry: `"event": "change_approved", "tier": 2, "approval_id": "uuid"`
|
|
1276
|
+
3. Proceed with execution
|
|
1277
|
+
|
|
1278
|
+
### Step 6 — On rejection
|
|
1279
|
+
1. Update approval JSON: `"status": "rejected"`
|
|
1280
|
+
2. Write AUDIT entry: `"event": "change_rejected", "tier": 2, "approval_id": "uuid"`
|
|
1281
|
+
3. Report to user: "Change rejected by [approver]. Reason: [notes]"
|
|
1282
|
+
4. Create a fix task: address the rejection reason and re-request approval
|
|
1283
|
+
|
|
1284
|
+
### Step 7 — On expiry
|
|
1285
|
+
1. Update approval JSON: `"status": "expired"`
|
|
1286
|
+
2. Write AUDIT entry with `"event": "approval_expired"`
|
|
1287
|
+
3. Escalate per the INTEGRATIONS-CONFIG.md escalation path
|
|
1288
|
+
4. Alert user and ask whether to re-request or escalate
|
|
1289
|
+
|
|
1290
|
+
## Override mechanism (emergency only)
|
|
1291
|
+
|
|
1292
|
+
For P0 incidents requiring immediate deployment:
|
|
1293
|
+
|
|
1294
|
+
```
|
|
1295
|
+
/mindforge:approve [approval-id] --emergency --reason "[justification]"
|
|
1296
|
+
```
|
|
1297
|
+
|
|
1298
|
+
Emergency overrides are:
|
|
1299
|
+
- Logged with `"emergency_override": true` in AUDIT
|
|
1300
|
+
- Flagged in the Slack notification channel
|
|
1301
|
+
- Subject to post-incident review (auto-creates a follow-up task)
|
|
1302
|
+
- Limited to users in the `EMERGENCY_APPROVERS` config list
|
|
1303
|
+
Never use emergency overrides for convenience — only for genuine production emergencies.
|
|
1304
|
+
```
|
|
1305
|
+
|
|
1306
|
+
---
|
|
1307
|
+
|
|
1308
|
+
### `.mindforge/governance/compliance-gates.md`
|
|
1309
|
+
|
|
1310
|
+
```markdown
|
|
1311
|
+
# MindForge Governance — Compliance Gates
|
|
1312
|
+
|
|
1313
|
+
## Purpose
|
|
1314
|
+
Define hard gates that block phase execution and PR creation when specific
|
|
1315
|
+
regulatory or security requirements are not met.
|
|
1316
|
+
These gates cannot be bypassed by approval — they must be resolved.
|
|
1317
|
+
|
|
1318
|
+
## Gate definitions
|
|
1319
|
+
|
|
1320
|
+
### Gate 1 — No open CRITICAL security findings
|
|
1321
|
+
**Trigger:** Any `security_finding` with `severity: "CRITICAL"` in the current
|
|
1322
|
+
phase's SECURITY-REVIEW file where `remediated: false`.
|
|
1323
|
+
|
|
1324
|
+
**Block:** Phase execution, PR creation, release tag.
|
|
1325
|
+
**Resolution:** Fix the finding, re-run `/mindforge:security-scan`, confirm remediated.
|
|
1326
|
+
**Override:** Not possible — CRITICAL findings must be fixed.
|
|
1327
|
+
|
|
1328
|
+
---
|
|
1329
|
+
|
|
1330
|
+
### Gate 2 — Test suite passing
|
|
1331
|
+
**Trigger:** Test suite exit code non-zero.
|
|
1332
|
+
|
|
1333
|
+
**Block:** Phase completion, PR creation.
|
|
1334
|
+
**Resolution:** Fix failing tests.
|
|
1335
|
+
**Override:** Not possible in standard mode. Emergency only with `--emergency`.
|
|
1336
|
+
|
|
1337
|
+
---
|
|
1338
|
+
|
|
1339
|
+
### Gate 3 — No secrets in diff
|
|
1340
|
+
**Trigger:** Secret detection scan finds any credential pattern in staged changes.
|
|
1341
|
+
|
|
1342
|
+
**Block:** Commit, PR creation.
|
|
1343
|
+
**Resolution:** Remove secret from code, rotate the credential immediately.
|
|
1344
|
+
**Override:** Not possible — a committed secret is a security incident.
|
|
1345
|
+
**Additional action:** If a secret was already committed, trigger the incident
|
|
1346
|
+
response protocol: `{ "event": "secret_committed", "severity": "CRITICAL" }`.
|
|
1347
|
+
|
|
1348
|
+
---
|
|
1349
|
+
|
|
1350
|
+
### Gate 4 — GDPR compliance (when data-privacy skill active)
|
|
1351
|
+
**Trigger:** New PII field added to schema without a documented retention period.
|
|
1352
|
+
|
|
1353
|
+
**Block:** Phase completion.
|
|
1354
|
+
**Resolution:** Add retention period to ARCHITECTURE.md data model.
|
|
1355
|
+
**Override:** Requires compliance officer approval (Tier 3).
|
|
1356
|
+
|
|
1357
|
+
---
|
|
1358
|
+
|
|
1359
|
+
### Gate 5 — Dependency CVE clearance
|
|
1360
|
+
**Trigger:** `npm audit` or `pip-audit` returns HIGH or CRITICAL CVE.
|
|
1361
|
+
|
|
1362
|
+
**Block:** PR creation.
|
|
1363
|
+
**Resolution:** Update the vulnerable dependency.
|
|
1364
|
+
**Override:** Requires security officer approval (Tier 3) with documented
|
|
1365
|
+
temporary mitigation.
|
|
1366
|
+
|
|
1367
|
+
---
|
|
1368
|
+
|
|
1369
|
+
## Gate execution
|
|
1370
|
+
|
|
1371
|
+
Run gates in this order (fail fast):
|
|
1372
|
+
|
|
1373
|
+
```
|
|
1374
|
+
Gate 3 (no secrets) → fastest, cheapest, most critical
|
|
1375
|
+
Gate 1 (no CRITICAL sec) → check SECURITY-REVIEW file
|
|
1376
|
+
Gate 2 (tests passing) → run test suite
|
|
1377
|
+
Gate 5 (CVE clearance) → npm audit
|
|
1378
|
+
Gate 4 (GDPR) → only if data-privacy skill was active
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
Write gate results to `.planning/phases/[N]/GATE-RESULTS-[N].md`:
|
|
1382
|
+
|
|
1383
|
+
```markdown
|
|
1384
|
+
# Compliance Gate Results — Phase [N]
|
|
1385
|
+
**Run at:** [ISO-8601]
|
|
1386
|
+
|
|
1387
|
+
| Gate | Status | Detail |
|
|
1388
|
+
|---|---|---|
|
|
1389
|
+
| Secret detection | ✅ PASS | 0 patterns found |
|
|
1390
|
+
| CRITICAL security findings | ✅ PASS | No open CRITICAL findings |
|
|
1391
|
+
| Test suite | ✅ PASS | 342 tests passing |
|
|
1392
|
+
| Dependency CVEs | ⚠️ WARN | 1 MODERATE CVE (below blocking threshold) |
|
|
1393
|
+
| GDPR retention | ✅ PASS | data-privacy skill not active this phase |
|
|
1394
|
+
|
|
1395
|
+
**Overall:** ✅ ALL BLOCKING GATES PASSED
|
|
1396
|
+
```
|
|
1397
|
+
```
|
|
1398
|
+
|
|
1399
|
+
**Commit:**
|
|
1400
|
+
```bash
|
|
1401
|
+
git add .mindforge/governance/
|
|
1402
|
+
git commit -m "feat(governance): implement change classifier, approval workflow, compliance gates"
|
|
1403
|
+
```
|
|
1404
|
+
|
|
1405
|
+
---
|
|
1406
|
+
|
|
1407
|
+
## TASK 6 — Write Multi-Developer HANDOFF System
|
|
1408
|
+
|
|
1409
|
+
### `.mindforge/team/multi-handoff.md`
|
|
1410
|
+
|
|
1411
|
+
```markdown
|
|
1412
|
+
# MindForge Team — Multi-Developer HANDOFF
|
|
1413
|
+
|
|
1414
|
+
## Purpose
|
|
1415
|
+
Enable multiple developers on the same project to each maintain their own
|
|
1416
|
+
MindForge session state without overwriting each other's HANDOFF.json.
|
|
1417
|
+
|
|
1418
|
+
## Problem with single HANDOFF.json in team environments
|
|
1419
|
+
If two developers both run MindForge on the same branch:
|
|
1420
|
+
- Developer A's session writes HANDOFF.json at 2pm
|
|
1421
|
+
- Developer B's session writes HANDOFF.json at 3pm
|
|
1422
|
+
- Developer A resumes at 4pm — reads B's state, not their own
|
|
1423
|
+
- Developer A continues from the wrong position
|
|
1424
|
+
|
|
1425
|
+
## Solution: Per-developer HANDOFF files
|
|
1426
|
+
|
|
1427
|
+
### File naming convention
|
|
1428
|
+
Instead of `.planning/HANDOFF.json`:
|
|
1429
|
+
|
|
1430
|
+
```
|
|
1431
|
+
.planning/HANDOFF.json ← Shared team state (phase-level)
|
|
1432
|
+
.planning/handoffs/HANDOFF-[dev-id].json ← Per-developer session state
|
|
1433
|
+
```
|
|
1434
|
+
|
|
1435
|
+
Where `[dev-id]` is derived from:
|
|
1436
|
+
1. `git config user.email` (primary — unique per developer)
|
|
1437
|
+
2. `$USER` environment variable (fallback)
|
|
1438
|
+
3. `[hostname]-[pid]` (last resort)
|
|
1439
|
+
|
|
1440
|
+
The dev-id is sanitised to be safe as a filename:
|
|
1441
|
+
`john@company.com → john-company-com`
|
|
1442
|
+
`john.smith → john-smith`
|
|
1443
|
+
|
|
1444
|
+
### File structure: per-developer HANDOFF
|
|
1445
|
+
|
|
1446
|
+
```json
|
|
1447
|
+
{
|
|
1448
|
+
"schema_version": "1.0.0",
|
|
1449
|
+
"developer_id": "john-company-com",
|
|
1450
|
+
"developer_email": "john@company.com",
|
|
1451
|
+
"project": "my-saas-app",
|
|
1452
|
+
"phase": 3,
|
|
1453
|
+
"plan": "02",
|
|
1454
|
+
"plan_step": "Implementing the RBAC middleware — step 3 of 5",
|
|
1455
|
+
"last_completed_task": {
|
|
1456
|
+
"description": "Created role definition schema",
|
|
1457
|
+
"commit_sha": "abc1234",
|
|
1458
|
+
"verified": true
|
|
1459
|
+
},
|
|
1460
|
+
"next_task": "Implement permission check middleware in src/middleware/rbac.ts",
|
|
1461
|
+
"in_progress": {
|
|
1462
|
+
"file": "src/middleware/rbac.ts",
|
|
1463
|
+
"intent": "Add hasPermission(userId, resource, action) function",
|
|
1464
|
+
"completed_steps": ["Read existing middleware structure", "Defined Permission type"],
|
|
1465
|
+
"remaining_steps": ["Implement hasPermission", "Add tests", "Verify"]
|
|
1466
|
+
},
|
|
1467
|
+
"blockers": [],
|
|
1468
|
+
"decisions_needed": [],
|
|
1469
|
+
"context_refs": [
|
|
1470
|
+
".planning/PROJECT.md",
|
|
1471
|
+
".planning/STATE.md",
|
|
1472
|
+
".planning/phases/3/PLAN-3-02.md"
|
|
1473
|
+
],
|
|
1474
|
+
"recent_commits": ["abc1234: feat(rbac): add role schema"],
|
|
1475
|
+
"recent_files": ["src/auth/roles.ts", "src/middleware/rbac.ts"],
|
|
1476
|
+
"agent_notes": "Using casbin library for permission checking per TOOLS.md",
|
|
1477
|
+
"_warning": "Never store secrets, tokens, or passwords in this file.",
|
|
1478
|
+
"updated_at": "ISO-8601"
|
|
1479
|
+
}
|
|
1480
|
+
```
|
|
1481
|
+
|
|
1482
|
+
### Shared team HANDOFF.json
|
|
1483
|
+
The shared `.planning/HANDOFF.json` contains only phase-level state —
|
|
1484
|
+
not session-level state. Updated by the developer who completes a phase task:
|
|
1485
|
+
|
|
1486
|
+
```json
|
|
1487
|
+
{
|
|
1488
|
+
"schema_version": "1.0.0",
|
|
1489
|
+
"project": "my-saas-app",
|
|
1490
|
+
"phase": 3,
|
|
1491
|
+
"plan": null,
|
|
1492
|
+
"last_completed_task": {
|
|
1493
|
+
"description": "Phase 3 execution started",
|
|
1494
|
+
"completed_plans": ["01"],
|
|
1495
|
+
"in_progress_plans": ["02", "03"]
|
|
1496
|
+
},
|
|
1497
|
+
"next_task": "Continue Phase 3 execution — Plans 02 and 03 in progress",
|
|
1498
|
+
"blockers": [],
|
|
1499
|
+
"decisions_needed": [],
|
|
1500
|
+
"context_refs": [
|
|
1501
|
+
".planning/PROJECT.md",
|
|
1502
|
+
".planning/STATE.md",
|
|
1503
|
+
".planning/phases/3/DEPENDENCY-GRAPH-3.md"
|
|
1504
|
+
],
|
|
1505
|
+
"active_developers": [
|
|
1506
|
+
{ "dev_id": "john-company-com", "plan": "02", "last_seen": "ISO-8601" },
|
|
1507
|
+
{ "dev_id": "jane-company-com", "plan": "03", "last_seen": "ISO-8601" }
|
|
1508
|
+
],
|
|
1509
|
+
"_warning": "Never store secrets, tokens, or passwords in this file.",
|
|
1510
|
+
"updated_at": "ISO-8601"
|
|
1511
|
+
}
|
|
1512
|
+
```
|
|
1513
|
+
|
|
1514
|
+
## Session start in team mode
|
|
1515
|
+
|
|
1516
|
+
When CLAUDE.md session start protocol runs in team mode:
|
|
1517
|
+
|
|
1518
|
+
1. Determine developer ID from `git config user.email`
|
|
1519
|
+
2. Check for per-developer HANDOFF: `.planning/handoffs/HANDOFF-[dev-id].json`
|
|
1520
|
+
3. If per-developer HANDOFF exists and is fresh (< 48 hours): load it as primary state
|
|
1521
|
+
4. Also read shared HANDOFF.json for team context (what others are working on)
|
|
1522
|
+
5. Present to developer:
|
|
1523
|
+
```
|
|
1524
|
+
Your session: Phase 3, Plan 02 (RBAC middleware)
|
|
1525
|
+
Team activity:
|
|
1526
|
+
- jane-company-com: working on Plan 03 (permission tests)
|
|
1527
|
+
|
|
1528
|
+
Continue from your last session? (yes/no)
|
|
1529
|
+
```
|
|
1530
|
+
|
|
1531
|
+
## Conflict detection
|
|
1532
|
+
|
|
1533
|
+
When two developers might be modifying the same files:
|
|
1534
|
+
|
|
1535
|
+
1. On session start: read shared HANDOFF.json `active_developers`
|
|
1536
|
+
2. Find your assigned plan (or the plan you are about to start)
|
|
1537
|
+
3. Check other developers' plans for file overlap using the dependency parser
|
|
1538
|
+
4. If overlap detected:
|
|
1539
|
+
```
|
|
1540
|
+
⚠️ File conflict detected:
|
|
1541
|
+
jane-company-com is working on Plan 03 which also modifies:
|
|
1542
|
+
- src/middleware/rbac.ts (you are also assigned this file in Plan 02)
|
|
1543
|
+
|
|
1544
|
+
Recommended: coordinate with jane before modifying this file.
|
|
1545
|
+
Options: 1) Wait for her plan to complete 2) Continue (risk merge conflict)
|
|
1546
|
+
```
|
|
1547
|
+
```
|
|
1548
|
+
|
|
1549
|
+
---
|
|
1550
|
+
|
|
1551
|
+
### `.mindforge/team/session-merger.md`
|
|
1552
|
+
|
|
1553
|
+
```markdown
|
|
1554
|
+
# MindForge Team — Session Merger
|
|
1555
|
+
|
|
1556
|
+
## Purpose
|
|
1557
|
+
When multiple developers complete work on the same branch, merge their
|
|
1558
|
+
session artifacts (SUMMARY files, AUDIT entries, STATE updates) into a
|
|
1559
|
+
coherent phase record.
|
|
1560
|
+
|
|
1561
|
+
## Merge protocol
|
|
1562
|
+
|
|
1563
|
+
### When to merge
|
|
1564
|
+
Run session merge when:
|
|
1565
|
+
- A developer pushes commits that include work from another developer
|
|
1566
|
+
- The branch is being prepared for a PR
|
|
1567
|
+
- `/mindforge:complete-milestone` is run with multiple active developers
|
|
1568
|
+
|
|
1569
|
+
### Merge steps
|
|
1570
|
+
|
|
1571
|
+
**Step 1 — Collect all per-developer session artifacts**
|
|
1572
|
+
```bash
|
|
1573
|
+
ls .planning/handoffs/HANDOFF-*.json
|
|
1574
|
+
```
|
|
1575
|
+
|
|
1576
|
+
**Step 2 — Merge AUDIT entries**
|
|
1577
|
+
All AUDIT entries from all developers' sessions are already in AUDIT.jsonl
|
|
1578
|
+
(assuming all developers committed their changes — git history = source of truth).
|
|
1579
|
+
No merge needed — AUDIT.jsonl is append-only and already contains all entries.
|
|
1580
|
+
|
|
1581
|
+
**Step 3 — Merge SUMMARY files**
|
|
1582
|
+
SUMMARY files are per-plan, per-developer. They should already be in the
|
|
1583
|
+
`.planning/phases/[N]/` directory from each developer's commits.
|
|
1584
|
+
Verify all expected SUMMARY files exist.
|
|
1585
|
+
|
|
1586
|
+
**Step 4 — Reconcile STATE.md**
|
|
1587
|
+
The shared STATE.md may have been updated by multiple developers.
|
|
1588
|
+
Use `git log --oneline .planning/STATE.md` to see the history.
|
|
1589
|
+
Generate a merged STATE.md that reflects the collective current state:
|
|
1590
|
+
- Phase status: complete if all plans have SUMMARY files
|
|
1591
|
+
- Decisions: union of all decisions from all sessions
|
|
1592
|
+
- Blockers: any unresolved blockers from any session
|
|
1593
|
+
|
|
1594
|
+
**Step 5 — Archive per-developer HANDOFFs**
|
|
1595
|
+
Move per-developer HANDOFF files to `.planning/handoffs/archived/`:
|
|
1596
|
+
```bash
|
|
1597
|
+
mv .planning/handoffs/HANDOFF-*.json .planning/handoffs/archived/
|
|
1598
|
+
```
|
|
1599
|
+
Leave only the shared HANDOFF.json in `.planning/handoffs/`.
|
|
1600
|
+
The shared HANDOFF.json is updated to reflect the merged state.
|
|
1601
|
+
```
|
|
1602
|
+
|
|
1603
|
+
**Commit:**
|
|
1604
|
+
```bash
|
|
1605
|
+
git add .mindforge/team/
|
|
1606
|
+
git commit -m "feat(team): implement multi-developer HANDOFF and session merger"
|
|
1607
|
+
```
|
|
1608
|
+
|
|
1609
|
+
---
|
|
1610
|
+
|
|
1611
|
+
## TASK 7 — Write AUDIT Archiving System
|
|
1612
|
+
|
|
1613
|
+
Add an archiving section to `.mindforge/audit/AUDIT-SCHEMA.md`:
|
|
1614
|
+
|
|
1615
|
+
```markdown
|
|
1616
|
+
## AUDIT.jsonl Archiving
|
|
1617
|
+
|
|
1618
|
+
### When to archive
|
|
1619
|
+
Archive AUDIT.jsonl when line count exceeds 10,000 entries.
|
|
1620
|
+
Check count: `wc -l .planning/AUDIT.jsonl`
|
|
1621
|
+
|
|
1622
|
+
### Archive protocol
|
|
1623
|
+
|
|
1624
|
+
```bash
|
|
1625
|
+
# 1. Determine archive filename (ISO-8601 date range)
|
|
1626
|
+
FIRST_DATE=$(head -1 .planning/AUDIT.jsonl | python3 -c "import sys,json; print(json.loads(sys.stdin.read())['timestamp'][:10])")
|
|
1627
|
+
LAST_DATE=$(tail -1 .planning/AUDIT.jsonl | python3 -c "import sys,json; print(json.loads(sys.stdin.read())['timestamp'][:10])")
|
|
1628
|
+
ARCHIVE_NAME="audit-${FIRST_DATE}-to-${LAST_DATE}.jsonl"
|
|
1629
|
+
|
|
1630
|
+
# 2. Copy to archive directory
|
|
1631
|
+
cp .planning/AUDIT.jsonl ".planning/audit-archive/${ARCHIVE_NAME}"
|
|
1632
|
+
|
|
1633
|
+
# 3. Write archive marker as first entry of new AUDIT.jsonl
|
|
1634
|
+
echo '{"id":"'$(uuidgen)'","timestamp":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","event":"audit_archive_created","archive_file":"'${ARCHIVE_NAME}'","entries_archived":'$(wc -l < .planning/AUDIT.jsonl)'}' > .planning/AUDIT.jsonl.new
|
|
1635
|
+
|
|
1636
|
+
# 4. Replace AUDIT.jsonl with the new file containing only the archive marker
|
|
1637
|
+
mv .planning/AUDIT.jsonl.new .planning/AUDIT.jsonl
|
|
1638
|
+
|
|
1639
|
+
# 5. Commit the archive
|
|
1640
|
+
git add .planning/audit-archive/${ARCHIVE_NAME} .planning/AUDIT.jsonl
|
|
1641
|
+
git commit -m "chore(audit): archive AUDIT.jsonl to ${ARCHIVE_NAME}"
|
|
1642
|
+
```
|
|
1643
|
+
|
|
1644
|
+
### Querying archived entries
|
|
1645
|
+
To search across current + archived logs:
|
|
1646
|
+
```bash
|
|
1647
|
+
# Search all audit logs (current + archives)
|
|
1648
|
+
cat .planning/AUDIT.jsonl .planning/audit-archive/*.jsonl 2>/dev/null \
|
|
1649
|
+
| grep '"event":"security_finding"' \
|
|
1650
|
+
| python3 -m json.tool
|
|
1651
|
+
```
|
|
1652
|
+
|
|
1653
|
+
### Archive retention
|
|
1654
|
+
Archive files are committed to git. They are part of the permanent project record.
|
|
1655
|
+
Do not delete archive files — they are the audit trail for past work.
|
|
1656
|
+
For very old projects with many archives: consider moving to a long-term storage
|
|
1657
|
+
solution and replacing with a summary index file.
|
|
1658
|
+
```
|
|
1659
|
+
|
|
1660
|
+
**Commit:**
|
|
1661
|
+
```bash
|
|
1662
|
+
git add .mindforge/audit/AUDIT-SCHEMA.md .planning/audit-archive/
|
|
1663
|
+
git commit -m "feat(audit): implement AUDIT.jsonl archiving protocol (10K line threshold)"
|
|
1664
|
+
```
|
|
1665
|
+
|
|
1666
|
+
---
|
|
1667
|
+
|
|
1668
|
+
## TASK 8 — Write `/mindforge:audit` command
|
|
1669
|
+
|
|
1670
|
+
### `.claude/commands/mindforge/audit.md`
|
|
1671
|
+
|
|
1672
|
+
```markdown
|
|
1673
|
+
# MindForge — Audit Command
|
|
1674
|
+
# Usage: /mindforge:audit [filter] [--phase N] [--event type] [--date YYYY-MM-DD]
|
|
1675
|
+
# [--since YYYY-MM-DD] [--severity S] [--export path]
|
|
1676
|
+
|
|
1677
|
+
## Purpose
|
|
1678
|
+
Query the append-only AUDIT.jsonl log with filters to produce actionable reports
|
|
1679
|
+
for governance, debugging, and compliance purposes.
|
|
1680
|
+
|
|
1681
|
+
## Available filters
|
|
1682
|
+
|
|
1683
|
+
| Flag | Description | Example |
|
|
1684
|
+
|---|---|---|
|
|
1685
|
+
| `--phase [N]` | Filter by phase number | `--phase 3` |
|
|
1686
|
+
| `--event [type]` | Filter by event type | `--event security_finding` |
|
|
1687
|
+
| `--date [YYYY-MM-DD]` | Filter by specific date | `--date 2026-03-20` |
|
|
1688
|
+
| `--since [YYYY-MM-DD]` | Filter from date onwards | `--since 2026-03-01` |
|
|
1689
|
+
| `--severity [level]` | Filter security findings by severity | `--severity CRITICAL` |
|
|
1690
|
+
| `--agent [name]` | Filter by which agent wrote the entry | `--agent mindforge-orchestrator` |
|
|
1691
|
+
| `--export [path]` | Export filtered results to a file | `--export audit-report.json` |
|
|
1692
|
+
| `--include-archived` | Also search archived AUDIT files | |
|
|
1693
|
+
| `--summary` | Show summary statistics instead of entries | |
|
|
1694
|
+
|
|
1695
|
+
## Output modes
|
|
1696
|
+
|
|
1697
|
+
### Default — formatted table
|
|
1698
|
+
```
|
|
1699
|
+
/mindforge:audit --phase 3
|
|
1700
|
+
|
|
1701
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1702
|
+
Audit Log — Phase 3 (47 entries)
|
|
1703
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1704
|
+
|
|
1705
|
+
2026-03-20 14:32:10 phase_planned Phase 3: 6 plans, 3 waves
|
|
1706
|
+
2026-03-20 14:33:22 task_started Plan 3-01: User model
|
|
1707
|
+
2026-03-20 14:45:18 task_completed ✅ Plan 3-01 — commit: abc1234
|
|
1708
|
+
2026-03-20 14:45:19 task_started Plan 3-02: Product model
|
|
1709
|
+
2026-03-20 14:51:33 security_finding 🔴 HIGH: A07 — weak session config
|
|
1710
|
+
2026-03-20 14:52:00 task_completed ✅ Plan 3-02 — commit: def5678
|
|
1711
|
+
2026-03-20 15:12:45 change_classified Tier 2 (new feature) — peer review
|
|
1712
|
+
2026-03-20 15:13:00 change_approved Approved by: john-company-com
|
|
1713
|
+
...
|
|
1714
|
+
|
|
1715
|
+
Showing 20 of 47 entries. Add --all to show all entries.
|
|
1716
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1717
|
+
```
|
|
1718
|
+
|
|
1719
|
+
### Summary mode (`--summary`)
|
|
1720
|
+
```
|
|
1721
|
+
/mindforge:audit --summary
|
|
1722
|
+
|
|
1723
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1724
|
+
Audit Summary — [Project Name]
|
|
1725
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1726
|
+
|
|
1727
|
+
Total entries : 342
|
|
1728
|
+
Date range : 2026-03-15 → 2026-03-20
|
|
1729
|
+
Phases covered : 1, 2, 3
|
|
1730
|
+
|
|
1731
|
+
Events by type:
|
|
1732
|
+
task_completed 87
|
|
1733
|
+
task_started 87
|
|
1734
|
+
security_finding 12
|
|
1735
|
+
context_compaction 5
|
|
1736
|
+
change_approved 8
|
|
1737
|
+
change_rejected 1
|
|
1738
|
+
quality_gate_failed 3
|
|
1739
|
+
|
|
1740
|
+
Security findings:
|
|
1741
|
+
🔴 CRITICAL: 0
|
|
1742
|
+
🟠 HIGH: 3 (all remediated)
|
|
1743
|
+
🟡 MEDIUM: 7 (4 open, 3 remediated)
|
|
1744
|
+
⚪ LOW: 2
|
|
1745
|
+
|
|
1746
|
+
Approvals:
|
|
1747
|
+
Tier 1 (auto): 79 changes
|
|
1748
|
+
Tier 2 (peer): 8 approved, 0 rejected
|
|
1749
|
+
Tier 3 (comp): 1 approved, 1 rejected
|
|
1750
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1751
|
+
```
|
|
1752
|
+
|
|
1753
|
+
### Security compliance report (`--event security_finding --export`)
|
|
1754
|
+
```
|
|
1755
|
+
/mindforge:audit --event security_finding --export security-compliance-report.md
|
|
1756
|
+
|
|
1757
|
+
Generates a formatted Markdown report of all security findings:
|
|
1758
|
+
- One row per finding with: date, phase, severity, OWASP category, file, remediated status
|
|
1759
|
+
- Summary table at the top: total by severity, remediation rate
|
|
1760
|
+
- Suitable for sharing with security auditors or compliance team
|
|
1761
|
+
```
|
|
1762
|
+
|
|
1763
|
+
## Reading from AUDIT.jsonl
|
|
1764
|
+
|
|
1765
|
+
```bash
|
|
1766
|
+
# Count total entries
|
|
1767
|
+
wc -l .planning/AUDIT.jsonl
|
|
1768
|
+
|
|
1769
|
+
# Filter by event type
|
|
1770
|
+
grep '"event":"security_finding"' .planning/AUDIT.jsonl | python3 -m json.tool
|
|
1771
|
+
|
|
1772
|
+
# Filter by date (entries containing today's date)
|
|
1773
|
+
grep "$(date -u +%Y-%m-%d)" .planning/AUDIT.jsonl
|
|
1774
|
+
|
|
1775
|
+
# Count events by type
|
|
1776
|
+
grep -o '"event":"[^"]*"' .planning/AUDIT.jsonl | sort | uniq -c | sort -rn
|
|
1777
|
+
|
|
1778
|
+
# Search including archives
|
|
1779
|
+
cat .planning/AUDIT.jsonl .planning/audit-archive/*.jsonl 2>/dev/null | grep '"severity":"CRITICAL"'
|
|
1780
|
+
```
|
|
1781
|
+
|
|
1782
|
+
## AUDIT integrity verification
|
|
1783
|
+
|
|
1784
|
+
Add `--verify` flag to check AUDIT.jsonl integrity:
|
|
1785
|
+
|
|
1786
|
+
```
|
|
1787
|
+
/mindforge:audit --verify
|
|
1788
|
+
|
|
1789
|
+
Verifying AUDIT.jsonl integrity...
|
|
1790
|
+
Total entries : 342
|
|
1791
|
+
Valid JSON : 342 / 342 ✅
|
|
1792
|
+
Required fields: 342 / 342 ✅
|
|
1793
|
+
Chronological : ✅ (all timestamps in order)
|
|
1794
|
+
No blank lines : ✅
|
|
1795
|
+
Archive marker : ✅ (previous archive referenced)
|
|
1796
|
+
|
|
1797
|
+
AUDIT.jsonl integrity: VERIFIED ✅
|
|
1798
|
+
```
|
|
1799
|
+
```
|
|
1800
|
+
|
|
1801
|
+
**Commit:**
|
|
1802
|
+
```bash
|
|
1803
|
+
cp .claude/commands/mindforge/audit.md .agent/mindforge/audit.md
|
|
1804
|
+
git add .claude/commands/mindforge/audit.md .agent/mindforge/audit.md
|
|
1805
|
+
git commit -m "feat(commands): add /mindforge:audit query and reporting command"
|
|
1806
|
+
```
|
|
1807
|
+
|
|
1808
|
+
---
|
|
1809
|
+
|
|
1810
|
+
## TASK 9 — Write `/mindforge:milestone` and `/mindforge:complete-milestone`
|
|
1811
|
+
|
|
1812
|
+
### `.claude/commands/mindforge/milestone.md`
|
|
1813
|
+
|
|
1814
|
+
```markdown
|
|
1815
|
+
# MindForge — Milestone Command
|
|
1816
|
+
# Usage: /mindforge:milestone [create|status|list]
|
|
1817
|
+
|
|
1818
|
+
## Milestone concept
|
|
1819
|
+
A milestone groups multiple phases into a shippable product version.
|
|
1820
|
+
Milestones map to semantic version releases (v1.0.0, v1.1.0, v2.0.0).
|
|
1821
|
+
|
|
1822
|
+
## milestone create
|
|
1823
|
+
|
|
1824
|
+
```
|
|
1825
|
+
/mindforge:milestone create [name]
|
|
1826
|
+
```
|
|
1827
|
+
|
|
1828
|
+
1. Ask:
|
|
1829
|
+
- "What is the milestone version? (e.g., v1.0.0)"
|
|
1830
|
+
- "What phases does this milestone include? (e.g., 1, 2, 3)"
|
|
1831
|
+
- "What is the milestone's definition of done? (what must be true to call this milestone shipped)"
|
|
1832
|
+
- "What is the target ship date? (optional)"
|
|
1833
|
+
|
|
1834
|
+
2. Write `.planning/milestones/MILESTONE-[name].md`:
|
|
1835
|
+
|
|
1836
|
+
```markdown
|
|
1837
|
+
# Milestone: [name]
|
|
1838
|
+
**Version:** v[X.Y.Z]
|
|
1839
|
+
**Phases:** [N, M, ...]
|
|
1840
|
+
**Target date:** [date or TBD]
|
|
1841
|
+
**Created:** [ISO-8601]
|
|
1842
|
+
**Status:** In progress
|
|
1843
|
+
|
|
1844
|
+
## Definition of done
|
|
1845
|
+
[From user input — must be testable]
|
|
1846
|
+
|
|
1847
|
+
## Phase completion status
|
|
1848
|
+
| Phase | Description | Status |
|
|
1849
|
+
|---|---|---|
|
|
1850
|
+
| Phase 1 | [description] | ✅ Complete |
|
|
1851
|
+
| Phase 2 | [description] | 🔄 In progress |
|
|
1852
|
+
| Phase 3 | [description] | ⏳ Not started |
|
|
1853
|
+
|
|
1854
|
+
## Checklist
|
|
1855
|
+
- [ ] All phases complete and UAT signed off
|
|
1856
|
+
- [ ] All CRITICAL and HIGH security findings remediated
|
|
1857
|
+
- [ ] CHANGELOG.md entry written
|
|
1858
|
+
- [ ] Documentation published to Confluence (if configured)
|
|
1859
|
+
- [ ] Release notes written
|
|
1860
|
+
- [ ] All compliance gates passed
|
|
1861
|
+
```
|
|
1862
|
+
|
|
1863
|
+
## milestone status
|
|
1864
|
+
|
|
1865
|
+
```
|
|
1866
|
+
/mindforge:milestone status [name]
|
|
1867
|
+
|
|
1868
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1869
|
+
Milestone: v1.0.0 — Initial Release
|
|
1870
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1871
|
+
Status : In progress
|
|
1872
|
+
Target : 2026-04-01
|
|
1873
|
+
Progress : 2 of 4 phases complete (50%)
|
|
1874
|
+
|
|
1875
|
+
Phase Progress:
|
|
1876
|
+
Phase 1 [████████████████████] 100% ✅
|
|
1877
|
+
Phase 2 [████████████████████] 100% ✅
|
|
1878
|
+
Phase 3 [████████████░░░░░░░░] 60% 🔄
|
|
1879
|
+
Phase 4 [░░░░░░░░░░░░░░░░░░░░] 0% ⏳
|
|
1880
|
+
|
|
1881
|
+
Open issues:
|
|
1882
|
+
🟠 2 HIGH security findings open (Phase 3)
|
|
1883
|
+
🔵 3 requirements not yet tested (Phase 3)
|
|
1884
|
+
|
|
1885
|
+
Milestone gates:
|
|
1886
|
+
[ ] All phases complete
|
|
1887
|
+
[ ] Zero open CRITICAL/HIGH security findings
|
|
1888
|
+
[ ] CHANGELOG.md written
|
|
1889
|
+
[ ] Release notes reviewed
|
|
1890
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1891
|
+
```
|
|
1892
|
+
|
|
1893
|
+
## milestone list
|
|
1894
|
+
|
|
1895
|
+
```
|
|
1896
|
+
/mindforge:milestone list
|
|
1897
|
+
|
|
1898
|
+
Milestones:
|
|
1899
|
+
v1.0.0 Initial Release In progress Phase 3/4 in progress
|
|
1900
|
+
v0.1.0 Beta Release Shipped ✅ 2026-03-15
|
|
1901
|
+
```
|
|
1902
|
+
```
|
|
1903
|
+
|
|
1904
|
+
---
|
|
1905
|
+
|
|
1906
|
+
### `.claude/commands/mindforge/complete-milestone.md`
|
|
1907
|
+
|
|
1908
|
+
```markdown
|
|
1909
|
+
# MindForge — Complete Milestone Command
|
|
1910
|
+
# Usage: /mindforge:complete-milestone [milestone-name]
|
|
1911
|
+
|
|
1912
|
+
## Purpose
|
|
1913
|
+
Archive a completed milestone, create a release tag, generate the milestone
|
|
1914
|
+
report, publish documentation, and prepare for the next milestone.
|
|
1915
|
+
|
|
1916
|
+
## Pre-checks (all must pass)
|
|
1917
|
+
|
|
1918
|
+
1. Read the milestone file: `.planning/milestones/MILESTONE-[name].md`
|
|
1919
|
+
2. Verify all phases in the milestone are complete (all SUMMARY files present, UAT signed off)
|
|
1920
|
+
3. Verify all compliance gates pass (`GATE-RESULTS-[N].md` for each phase)
|
|
1921
|
+
4. Verify no open CRITICAL or HIGH security findings
|
|
1922
|
+
5. Verify CHANGELOG.md has an entry for this milestone's version
|
|
1923
|
+
|
|
1924
|
+
If any check fails: report which checks failed and what must be done.
|
|
1925
|
+
Do not proceed until all pass.
|
|
1926
|
+
|
|
1927
|
+
## Step 1 — Run final security scan
|
|
1928
|
+
|
|
1929
|
+
```bash
|
|
1930
|
+
/mindforge:security-scan --deep --deps
|
|
1931
|
+
```
|
|
1932
|
+
|
|
1933
|
+
If CRITICAL findings: stop. Must be resolved before milestone completion.
|
|
1934
|
+
|
|
1935
|
+
## Step 2 — Generate milestone report
|
|
1936
|
+
|
|
1937
|
+
Write `.planning/milestones/MILESTONE-[name]-REPORT.md`:
|
|
1938
|
+
|
|
1939
|
+
```markdown
|
|
1940
|
+
# Milestone Report: [name] — v[X.Y.Z]
|
|
1941
|
+
**Completed:** [ISO-8601]
|
|
1942
|
+
**Duration:** [start date] → [end date] ([N] days)
|
|
1943
|
+
|
|
1944
|
+
## Delivered
|
|
1945
|
+
[List all user-facing features from phase descriptions and SUMMARY files]
|
|
1946
|
+
|
|
1947
|
+
## Requirements delivered
|
|
1948
|
+
[Summarise REQUIREMENTS.md v1 items and their verification status]
|
|
1949
|
+
|
|
1950
|
+
## Phases completed
|
|
1951
|
+
| Phase | Description | Tasks | Commits | Duration |
|
|
1952
|
+
|---|---|---|---|---|
|
|
1953
|
+
| 1 | [desc] | [N] | [N] | [N] days |
|
|
1954
|
+
| 2 | [desc] | [N] | [N] | [N] days |
|
|
1955
|
+
|
|
1956
|
+
## Quality metrics
|
|
1957
|
+
- Total tasks: [N]
|
|
1958
|
+
- Total commits: [N]
|
|
1959
|
+
- Test coverage: [X]%
|
|
1960
|
+
- Security findings: [N] total, [N] remediated, 0 open (CRITICAL/HIGH)
|
|
1961
|
+
- Technical debt added: [items from SUMMARY files marked as tech debt]
|
|
1962
|
+
|
|
1963
|
+
## Architecture decisions made
|
|
1964
|
+
[List all ADRs created in this milestone]
|
|
1965
|
+
|
|
1966
|
+
## Known limitations and tech debt
|
|
1967
|
+
[Any ⚠️ items from VERIFICATION.md or SUMMARY files flagged as future work]
|
|
1968
|
+
|
|
1969
|
+
## Release notes
|
|
1970
|
+
[Human-readable summary of what was built — suitable for a product changelog]
|
|
1971
|
+
```
|
|
1972
|
+
|
|
1973
|
+
## Step 3 — Update CHANGELOG.md
|
|
1974
|
+
|
|
1975
|
+
If the CHANGELOG entry is a draft, finalise it:
|
|
1976
|
+
- Add the exact release date
|
|
1977
|
+
- Review and clean up the entry
|
|
1978
|
+
- Ensure it follows Keep a Changelog format
|
|
1979
|
+
|
|
1980
|
+
## Step 4 — Publish to Confluence (if configured)
|
|
1981
|
+
|
|
1982
|
+
If Confluence integration is active:
|
|
1983
|
+
- Publish CHANGELOG.md to Confluence
|
|
1984
|
+
- Publish the milestone report to `[Space]/Releases/[milestone-name]`
|
|
1985
|
+
- Update the Architecture page if ARCHITECTURE.md was changed this milestone
|
|
1986
|
+
|
|
1987
|
+
## Step 5 — Create release tag
|
|
1988
|
+
|
|
1989
|
+
```bash
|
|
1990
|
+
# Tag the HEAD commit with the milestone version
|
|
1991
|
+
git tag -a "v${VERSION}" \
|
|
1992
|
+
-m "Milestone: ${MILESTONE_NAME} — ${DESCRIPTION}
|
|
1993
|
+
|
|
1994
|
+
Phases: ${PHASE_LIST}
|
|
1995
|
+
Released: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
1996
|
+
|
|
1997
|
+
git push origin "v${VERSION}"
|
|
1998
|
+
```
|
|
1999
|
+
|
|
2000
|
+
## Step 6 — Create GitHub/GitLab release (if configured)
|
|
2001
|
+
|
|
2002
|
+
If GitHub integration is active:
|
|
2003
|
+
```bash
|
|
2004
|
+
curl -s -X POST \
|
|
2005
|
+
-H "Authorization: Bearer ${GITHUB_TOKEN}" \
|
|
2006
|
+
-H "Content-Type: application/json" \
|
|
2007
|
+
-d '{
|
|
2008
|
+
"tag_name": "v'${VERSION}'",
|
|
2009
|
+
"name": "v'${VERSION}' — '${MILESTONE_NAME}'",
|
|
2010
|
+
"body": "'${RELEASE_NOTES_ESCAPED}'",
|
|
2011
|
+
"draft": false,
|
|
2012
|
+
"prerelease": false
|
|
2013
|
+
}' \
|
|
2014
|
+
"https://api.github.com/repos/${GITHUB_REPO}/releases"
|
|
2015
|
+
```
|
|
2016
|
+
|
|
2017
|
+
## Step 7 — Send Slack milestone notification (if configured)
|
|
2018
|
+
|
|
2019
|
+
Use the milestone completion Slack template with:
|
|
2020
|
+
- Milestone name and version
|
|
2021
|
+
- Summary of features delivered
|
|
2022
|
+
- Link to GitHub/GitLab release
|
|
2023
|
+
- Link to Confluence milestone report (if published)
|
|
2024
|
+
|
|
2025
|
+
## Step 8 — Archive milestone and update STATE.md
|
|
2026
|
+
|
|
2027
|
+
```bash
|
|
2028
|
+
# Archive planning artifacts for this milestone
|
|
2029
|
+
mkdir -p .planning/archive/milestone-[name]
|
|
2030
|
+
cp -r .planning/phases/ .planning/archive/milestone-[name]/
|
|
2031
|
+
cp .planning/REQUIREMENTS.md .planning/archive/milestone-[name]/
|
|
2032
|
+
cp .planning/ARCHITECTURE.md .planning/archive/milestone-[name]/
|
|
2033
|
+
```
|
|
2034
|
+
|
|
2035
|
+
Update STATE.md:
|
|
2036
|
+
```markdown
|
|
2037
|
+
## Milestone [name] — v[X.Y.Z] — COMPLETED [date]
|
|
2038
|
+
All [N] phases shipped. See .planning/milestones/MILESTONE-[name]-REPORT.md
|
|
2039
|
+
|
|
2040
|
+
## Current status
|
|
2041
|
+
Ready for next milestone. Run /mindforge:milestone create [next-version].
|
|
2042
|
+
```
|
|
2043
|
+
|
|
2044
|
+
## Step 9 — Write AUDIT entries
|
|
2045
|
+
|
|
2046
|
+
```json
|
|
2047
|
+
{ "event": "milestone_completed", "milestone": "v1.0.0", "phases_included": [1,2,3,4], "release_tag": "v1.0.0" }
|
|
2048
|
+
{ "event": "release_tag_created", "tag": "v1.0.0", "commit_sha": "[sha]" }
|
|
2049
|
+
```
|
|
2050
|
+
|
|
2051
|
+
## Step 10 — Report to user
|
|
2052
|
+
|
|
2053
|
+
```
|
|
2054
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2055
|
+
✅ Milestone v[X.Y.Z] — [name] — COMPLETE
|
|
2056
|
+
|
|
2057
|
+
Phases shipped : [N]
|
|
2058
|
+
Tasks completed : [N]
|
|
2059
|
+
Release tag : v[X.Y.Z]
|
|
2060
|
+
Confluence : Published ✅ / Skipped (not configured)
|
|
2061
|
+
GitHub Release : Created ✅ / Skipped (not configured)
|
|
2062
|
+
Slack : Notified ✅ / Skipped (not configured)
|
|
2063
|
+
|
|
2064
|
+
Next milestone: Run /mindforge:milestone create [next-version]
|
|
2065
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2066
|
+
```
|
|
2067
|
+
```
|
|
2068
|
+
|
|
2069
|
+
**Commit:**
|
|
2070
|
+
```bash
|
|
2071
|
+
cp .claude/commands/mindforge/milestone.md .agent/mindforge/milestone.md
|
|
2072
|
+
cp .claude/commands/mindforge/complete-milestone.md .agent/mindforge/complete-milestone.md
|
|
2073
|
+
git add .claude/commands/mindforge/milestone.md \
|
|
2074
|
+
.claude/commands/mindforge/complete-milestone.md \
|
|
2075
|
+
.agent/mindforge/milestone.md \
|
|
2076
|
+
.agent/mindforge/complete-milestone.md
|
|
2077
|
+
git commit -m "feat(commands): add /mindforge:milestone and /mindforge:complete-milestone"
|
|
2078
|
+
```
|
|
2079
|
+
|
|
2080
|
+
---
|
|
2081
|
+
|
|
2082
|
+
## TASK 10 — Write `/mindforge:approve` command
|
|
2083
|
+
|
|
2084
|
+
### `.claude/commands/mindforge/approve.md`
|
|
2085
|
+
|
|
2086
|
+
```markdown
|
|
2087
|
+
# MindForge — Approve Command
|
|
2088
|
+
# Usage: /mindforge:approve [approval-id] [--reject] [--emergency] [--reason "text"]
|
|
2089
|
+
|
|
2090
|
+
## Purpose
|
|
2091
|
+
Process a pending approval request for a Tier 2 or Tier 3 change.
|
|
2092
|
+
This command is run by the designated approver, not the agent.
|
|
2093
|
+
|
|
2094
|
+
## Listing pending approvals
|
|
2095
|
+
|
|
2096
|
+
```
|
|
2097
|
+
/mindforge:approve
|
|
2098
|
+
|
|
2099
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2100
|
+
Pending Approvals
|
|
2101
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2102
|
+
|
|
2103
|
+
[1] ID: abc-123 TIER 2 Phase 3, Plan 02
|
|
2104
|
+
Change: Add user RBAC with admin/editor/viewer roles
|
|
2105
|
+
Requested: 2026-03-20 14:32 (2 hours ago)
|
|
2106
|
+
Expires: 2026-03-22 14:32 (46 hours remaining)
|
|
2107
|
+
Risk: Medium — affects all authenticated routes
|
|
2108
|
+
|
|
2109
|
+
[2] ID: def-456 TIER 3 Phase 3, Plan 04
|
|
2110
|
+
Change: Implement payment processing via Stripe
|
|
2111
|
+
Requested: 2026-03-20 15:00 (1 hour ago)
|
|
2112
|
+
Expires: 2026-03-20 19:00 (3 hours remaining) ⚠️ URGENT
|
|
2113
|
+
Risk: High — financial data handling, PCI DSS scope
|
|
2114
|
+
|
|
2115
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2116
|
+
```
|
|
2117
|
+
|
|
2118
|
+
## Approving a change
|
|
2119
|
+
|
|
2120
|
+
```
|
|
2121
|
+
/mindforge:approve abc-123 --reason "Reviewed RBAC design. Approved."
|
|
2122
|
+
```
|
|
2123
|
+
|
|
2124
|
+
1. Read `.planning/approvals/APPROVAL-abc-123.json`
|
|
2125
|
+
2. Verify approval request is still PENDING (not expired, not already resolved)
|
|
2126
|
+
3. Verify the runner's identity matches the designated approver:
|
|
2127
|
+
```bash
|
|
2128
|
+
git config user.email
|
|
2129
|
+
# Must match the approver field in the approval request
|
|
2130
|
+
```
|
|
2131
|
+
4. Update the approval file:
|
|
2132
|
+
```json
|
|
2133
|
+
{
|
|
2134
|
+
"status": "approved",
|
|
2135
|
+
"resolved_at": "ISO-8601",
|
|
2136
|
+
"resolver_notes": "Reviewed RBAC design. Approved."
|
|
2137
|
+
}
|
|
2138
|
+
```
|
|
2139
|
+
5. Write AUDIT entry: `"event": "change_approved"`
|
|
2140
|
+
6. Update Slack thread (if configured): reply to approval request thread with ✅ message
|
|
2141
|
+
7. Update Jira ticket status (if configured): transition to "Approved"
|
|
2142
|
+
8. Notify the requesting developer:
|
|
2143
|
+
```
|
|
2144
|
+
✅ Approval abc-123 approved by [approver].
|
|
2145
|
+
Execution can now proceed.
|
|
2146
|
+
Run /mindforge:execute-phase [N] to continue.
|
|
2147
|
+
```
|
|
2148
|
+
|
|
2149
|
+
## Rejecting a change
|
|
2150
|
+
|
|
2151
|
+
```
|
|
2152
|
+
/mindforge:approve abc-123 --reject --reason "RBAC implementation must use existing AuthN library"
|
|
2153
|
+
```
|
|
2154
|
+
|
|
2155
|
+
1. Update approval file: `"status": "rejected"`
|
|
2156
|
+
2. Write AUDIT entry: `"event": "change_rejected"`
|
|
2157
|
+
3. Update Slack with ❌ message and reason
|
|
2158
|
+
4. Notify requester with the rejection reason and guidance on how to revise
|
|
2159
|
+
|
|
2160
|
+
## Emergency approval
|
|
2161
|
+
|
|
2162
|
+
```
|
|
2163
|
+
/mindforge:approve def-456 --emergency --reason "P0 production outage — payment processing down"
|
|
2164
|
+
```
|
|
2165
|
+
|
|
2166
|
+
Emergency approvals:
|
|
2167
|
+
1. Verify emergency approver is authorised (check `EMERGENCY_APPROVERS` in config)
|
|
2168
|
+
2. Set `"emergency_override": true` in approval file
|
|
2169
|
+
3. Write AUDIT entry with `"emergency_override": true`
|
|
2170
|
+
4. Post Slack notification with `@channel` mention flagging the emergency
|
|
2171
|
+
5. Create a follow-up task: "Post-incident review of emergency approval [id]"
|
|
2172
|
+
6. Proceed with execution immediately
|
|
2173
|
+
|
|
2174
|
+
## Approval expiry handling
|
|
2175
|
+
|
|
2176
|
+
At the start of each session, check for expired approvals:
|
|
2177
|
+
|
|
2178
|
+
```bash
|
|
2179
|
+
# Find approvals where expires_at < now and status = pending
|
|
2180
|
+
for APPROVAL_FILE in .planning/approvals/APPROVAL-*.json; do
|
|
2181
|
+
python3 -c "
|
|
2182
|
+
import json, datetime, sys
|
|
2183
|
+
data = json.load(open('${APPROVAL_FILE}'))
|
|
2184
|
+
if data['status'] == 'pending':
|
|
2185
|
+
expires = datetime.datetime.fromisoformat(data['expires_at'].replace('Z','+00:00'))
|
|
2186
|
+
if expires < datetime.datetime.now(datetime.timezone.utc):
|
|
2187
|
+
print('EXPIRED: ' + data['id'])
|
|
2188
|
+
"
|
|
2189
|
+
done
|
|
2190
|
+
```
|
|
2191
|
+
|
|
2192
|
+
For each expired approval:
|
|
2193
|
+
1. Update status to `expired`
|
|
2194
|
+
2. Write AUDIT entry: `"event": "approval_expired"`
|
|
2195
|
+
3. Alert the user and offer to re-request with updated information
|
|
2196
|
+
```
|
|
2197
|
+
|
|
2198
|
+
**Commit:**
|
|
2199
|
+
```bash
|
|
2200
|
+
cp .claude/commands/mindforge/approve.md .agent/mindforge/approve.md
|
|
2201
|
+
git add .claude/commands/mindforge/approve.md .agent/mindforge/approve.md
|
|
2202
|
+
git commit -m "feat(commands): add /mindforge:approve approval workflow command"
|
|
2203
|
+
```
|
|
2204
|
+
|
|
2205
|
+
---
|
|
2206
|
+
|
|
2207
|
+
## TASK 11 — Write `/mindforge:sync-jira` and `/mindforge:sync-confluence`
|
|
2208
|
+
|
|
2209
|
+
### `.claude/commands/mindforge/sync-jira.md`
|
|
2210
|
+
|
|
2211
|
+
```markdown
|
|
2212
|
+
# MindForge — Sync Jira Command
|
|
2213
|
+
# Usage: /mindforge:sync-jira [--phase N] [--dry-run] [--force]
|
|
2214
|
+
|
|
2215
|
+
## Purpose
|
|
2216
|
+
Synchronise MindForge project state with Jira.
|
|
2217
|
+
Creates/updates epics, stories, and bugs based on current planning artifacts.
|
|
2218
|
+
|
|
2219
|
+
## Pre-checks
|
|
2220
|
+
1. Verify Jira integration is configured: check `JIRA_API_TOKEN` env var exists
|
|
2221
|
+
2. Run connection health check (per `connection-manager.md`)
|
|
2222
|
+
3. If `--dry-run`: show what would be created/updated without making changes
|
|
2223
|
+
|
|
2224
|
+
## Step 1 — Establish what needs syncing
|
|
2225
|
+
|
|
2226
|
+
Read `.planning/jira-sync.json` to determine current sync state.
|
|
2227
|
+
Compare against current `.planning/` artifacts:
|
|
2228
|
+
|
|
2229
|
+
```
|
|
2230
|
+
For each phase in ROADMAP.md:
|
|
2231
|
+
- Does a Jira Epic exist? (check jira-sync.json phase_mappings)
|
|
2232
|
+
NO → create Epic
|
|
2233
|
+
YES → update Epic status if phase status changed
|
|
2234
|
+
|
|
2235
|
+
For each PLAN file in the phase:
|
|
2236
|
+
- Does a Jira Story exist? (check jira-sync.json story_keys)
|
|
2237
|
+
NO → create Story
|
|
2238
|
+
YES → update Story status based on SUMMARY file status
|
|
2239
|
+
|
|
2240
|
+
For each entry in AUDIT.jsonl where event = "security_finding":
|
|
2241
|
+
- Does a Jira Bug exist? (check jira-sync.json security_bugs)
|
|
2242
|
+
NO → create Bug
|
|
2243
|
+
YES → update Bug status (add comment if remediated)
|
|
2244
|
+
```
|
|
2245
|
+
|
|
2246
|
+
## Step 2 — Execute sync operations
|
|
2247
|
+
|
|
2248
|
+
Use the Jira API operations from `jira.md`.
|
|
2249
|
+
|
|
2250
|
+
For each operation:
|
|
2251
|
+
1. Execute the API call
|
|
2252
|
+
2. Record the result (Jira key) in `jira-sync.json`
|
|
2253
|
+
3. Write AUDIT entry for the integration action
|
|
2254
|
+
|
|
2255
|
+
## Step 3 — Report sync results
|
|
2256
|
+
|
|
2257
|
+
```
|
|
2258
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2259
|
+
Jira Sync Complete
|
|
2260
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2261
|
+
Created:
|
|
2262
|
+
3 Epics (Phases 1, 2, 3) → ENG-42, ENG-58, ENG-71
|
|
2263
|
+
12 Stories (all plans) → ENG-43 through ENG-55
|
|
2264
|
+
2 Security Bugs → ENG-88, ENG-89
|
|
2265
|
+
|
|
2266
|
+
Updated:
|
|
2267
|
+
5 Story statuses → Done (completed plans)
|
|
2268
|
+
1 Epic status → Done (Phase 1 complete)
|
|
2269
|
+
|
|
2270
|
+
Skipped:
|
|
2271
|
+
Phase 4 (not yet planned — no PLAN files)
|
|
2272
|
+
|
|
2273
|
+
Conflicts: 0
|
|
2274
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2275
|
+
```
|
|
2276
|
+
|
|
2277
|
+
## --dry-run mode
|
|
2278
|
+
Show all operations that would be performed without executing them.
|
|
2279
|
+
Format each as: `[CREATE/UPDATE] [Epic/Story/Bug] "[title]" → [what would happen]`
|
|
2280
|
+
```
|
|
2281
|
+
|
|
2282
|
+
---
|
|
2283
|
+
|
|
2284
|
+
### `.claude/commands/mindforge/sync-confluence.md`
|
|
2285
|
+
|
|
2286
|
+
```markdown
|
|
2287
|
+
# MindForge — Sync Confluence Command
|
|
2288
|
+
# Usage: /mindforge:sync-confluence [--page architecture|adrs|phases|all] [--dry-run]
|
|
2289
|
+
|
|
2290
|
+
## Purpose
|
|
2291
|
+
Publish MindForge planning artifacts to Confluence.
|
|
2292
|
+
|
|
2293
|
+
## Pages published
|
|
2294
|
+
|
|
2295
|
+
### `--page architecture`
|
|
2296
|
+
Publish `.planning/ARCHITECTURE.md` to:
|
|
2297
|
+
`[CONFLUENCE_SPACE_KEY] / Engineering / MindForge Architecture`
|
|
2298
|
+
|
|
2299
|
+
Conversion: Markdown → Confluence Wiki Markup
|
|
2300
|
+
(per conversion rules in `confluence.md`)
|
|
2301
|
+
|
|
2302
|
+
### `--page adrs`
|
|
2303
|
+
Publish each `.planning/decisions/ADR-*.md` to:
|
|
2304
|
+
`[CONFLUENCE_SPACE_KEY] / Engineering / Architecture Decision Records / [ADR title]`
|
|
2305
|
+
|
|
2306
|
+
### `--page phases`
|
|
2307
|
+
Publish phase documentation for all completed phases:
|
|
2308
|
+
- VERIFICATION.md → `Sprint Docs / Phase N Verification`
|
|
2309
|
+
- UAT.md → `Sprint Docs / Phase N UAT`
|
|
2310
|
+
- WAVE-REPORT.md → `Sprint Docs / Phase N Execution Report`
|
|
2311
|
+
|
|
2312
|
+
### `--page all`
|
|
2313
|
+
Publish all of the above.
|
|
2314
|
+
|
|
2315
|
+
## Sync report
|
|
2316
|
+
|
|
2317
|
+
```
|
|
2318
|
+
Confluence Sync Complete
|
|
2319
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2320
|
+
Created:
|
|
2321
|
+
Architecture page (new) → page ID: 123456
|
|
2322
|
+
ADR-001 (new) → page ID: 234567
|
|
2323
|
+
ADR-002 (new) → page ID: 234568
|
|
2324
|
+
Phase 1 Verification (new) → page ID: 345678
|
|
2325
|
+
|
|
2326
|
+
Updated:
|
|
2327
|
+
Architecture page (v4 → v5) — 3 sections changed
|
|
2328
|
+
|
|
2329
|
+
Skipped:
|
|
2330
|
+
Phase 2 (not yet complete — no VERIFICATION.md)
|
|
2331
|
+
|
|
2332
|
+
Confluence space: ENG
|
|
2333
|
+
Base URL: https://your-org.atlassian.net/wiki
|
|
2334
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
2335
|
+
```
|
|
2336
|
+
```
|
|
2337
|
+
|
|
2338
|
+
**Commit:**
|
|
2339
|
+
```bash
|
|
2340
|
+
cp .claude/commands/mindforge/sync-jira.md .agent/mindforge/sync-jira.md
|
|
2341
|
+
cp .claude/commands/mindforge/sync-confluence.md .agent/mindforge/sync-confluence.md
|
|
2342
|
+
git add .claude/commands/mindforge/sync-jira.md \
|
|
2343
|
+
.claude/commands/mindforge/sync-confluence.md \
|
|
2344
|
+
.agent/mindforge/sync-jira.md \
|
|
2345
|
+
.agent/mindforge/sync-confluence.md
|
|
2346
|
+
git commit -m "feat(commands): add /mindforge:sync-jira and /mindforge:sync-confluence"
|
|
2347
|
+
```
|
|
2348
|
+
|
|
2349
|
+
---
|
|
2350
|
+
|
|
2351
|
+
## TASK 12 — Update CLAUDE.md for Day 4 capabilities
|
|
2352
|
+
|
|
2353
|
+
Add to `.claude/CLAUDE.md` (and mirror to `.agent/CLAUDE.md`):
|
|
2354
|
+
|
|
2355
|
+
```markdown
|
|
2356
|
+
---
|
|
2357
|
+
|
|
2358
|
+
## GOVERNANCE LAYER (Day 4)
|
|
2359
|
+
|
|
2360
|
+
### Change classification is mandatory
|
|
2361
|
+
Before every phase execution and before every PR creation, run the change
|
|
2362
|
+
classifier: `.mindforge/governance/change-classifier.md`
|
|
2363
|
+
|
|
2364
|
+
Tier 1: auto-proceed after quality gates
|
|
2365
|
+
Tier 2: require peer review — create approval request, notify via Slack if configured
|
|
2366
|
+
Tier 3: require compliance review — create approval request, Jira ticket if configured
|
|
2367
|
+
|
|
2368
|
+
### Compliance gates block execution
|
|
2369
|
+
The five compliance gates in `.mindforge/governance/compliance-gates.md`
|
|
2370
|
+
are non-negotiable. No phase completes with open CRITICAL security findings.
|
|
2371
|
+
No PR is created with a secret in the diff. No exceptions.
|
|
2372
|
+
|
|
2373
|
+
### Approvals are tracked
|
|
2374
|
+
Approval requests are written to `.planning/approvals/APPROVAL-[uuid].json`.
|
|
2375
|
+
The AUDIT log records every approval, rejection, and emergency override.
|
|
2376
|
+
Run `/mindforge:approve` to list pending approvals.
|
|
2377
|
+
|
|
2378
|
+
### Integration actions are logged
|
|
2379
|
+
Every Jira, Confluence, Slack, and GitHub/GitLab action writes an AUDIT entry
|
|
2380
|
+
with event type `integration_action`. Integration failures are non-fatal —
|
|
2381
|
+
log the failure and continue. Never fail a phase because an integration is down.
|
|
2382
|
+
|
|
2383
|
+
### Multi-developer awareness
|
|
2384
|
+
In team environments: check `.planning/HANDOFF.json active_developers`
|
|
2385
|
+
at session start. Detect file conflicts with other active developers before
|
|
2386
|
+
beginning a plan. Write to per-developer HANDOFF:
|
|
2387
|
+
`.planning/handoffs/HANDOFF-[dev-id].json`
|
|
2388
|
+
|
|
2389
|
+
### AUDIT archiving
|
|
2390
|
+
If `.planning/AUDIT.jsonl` exceeds 10,000 lines:
|
|
2391
|
+
Run the archive protocol from `.mindforge/audit/AUDIT-SCHEMA.md` before
|
|
2392
|
+
writing any new entries.
|
|
2393
|
+
|
|
2394
|
+
### New commands available (Day 4)
|
|
2395
|
+
- `/mindforge:audit` — query audit log with filters
|
|
2396
|
+
- `/mindforge:milestone` — create and track milestones
|
|
2397
|
+
- `/mindforge:complete-milestone` — ship a milestone
|
|
2398
|
+
- `/mindforge:approve` — process approval requests
|
|
2399
|
+
- `/mindforge:sync-jira` — sync with Jira
|
|
2400
|
+
- `/mindforge:sync-confluence` — publish to Confluence
|
|
2401
|
+
|
|
2402
|
+
---
|
|
2403
|
+
```
|
|
2404
|
+
|
|
2405
|
+
**Commit:**
|
|
2406
|
+
```bash
|
|
2407
|
+
git add .claude/CLAUDE.md .agent/CLAUDE.md
|
|
2408
|
+
git commit -m "feat(core): update CLAUDE.md with Day 4 governance and integrations"
|
|
2409
|
+
```
|
|
2410
|
+
|
|
2411
|
+
---
|
|
2412
|
+
|
|
2413
|
+
## TASK 13 — Write Day 4 test suites
|
|
2414
|
+
|
|
2415
|
+
### `tests/integrations.test.js`
|
|
2416
|
+
|
|
2417
|
+
```javascript
|
|
2418
|
+
/**
|
|
2419
|
+
* MindForge Day 4 — Integrations Tests
|
|
2420
|
+
* Run: node tests/integrations.test.js
|
|
2421
|
+
*/
|
|
2422
|
+
|
|
2423
|
+
const fs = require('fs');
|
|
2424
|
+
const path = require('path');
|
|
2425
|
+
const assert = require('assert');
|
|
2426
|
+
|
|
2427
|
+
let passed = 0;
|
|
2428
|
+
let failed = 0;
|
|
2429
|
+
|
|
2430
|
+
function test(name, fn) {
|
|
2431
|
+
try { fn(); console.log(` ✅ ${name}`); passed++; }
|
|
2432
|
+
catch (err) { console.error(` ❌ ${name}\n ${err.message}`); failed++; }
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
2436
|
+
function readMd(p) { return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : ''; }
|
|
2437
|
+
|
|
2438
|
+
// ── Tests ─────────────────────────────────────────────────────────────────────
|
|
2439
|
+
console.log('\nMindForge Day 4 — Integration Tests\n');
|
|
2440
|
+
|
|
2441
|
+
console.log('Integration engine files:');
|
|
2442
|
+
const integrationFiles = [
|
|
2443
|
+
'connection-manager.md', 'jira.md', 'confluence.md',
|
|
2444
|
+
'slack.md', 'github.md', 'gitlab.md'
|
|
2445
|
+
];
|
|
2446
|
+
integrationFiles.forEach(f => {
|
|
2447
|
+
test(`${f} exists`, () => assert.ok(
|
|
2448
|
+
fs.existsSync(`.mindforge/integrations/${f}`), `Missing: .mindforge/integrations/${f}`
|
|
2449
|
+
));
|
|
2450
|
+
});
|
|
2451
|
+
|
|
2452
|
+
test('all integration files have content (> 500 chars)', () => {
|
|
2453
|
+
integrationFiles.forEach(f => {
|
|
2454
|
+
const content = readMd(`.mindforge/integrations/${f}`);
|
|
2455
|
+
assert.ok(content.length > 500, `${f} is too short (${content.length} chars)`);
|
|
2456
|
+
});
|
|
2457
|
+
});
|
|
2458
|
+
|
|
2459
|
+
console.log('\nConnection manager:');
|
|
2460
|
+
|
|
2461
|
+
test('connection-manager defines all 5 availability states', () => {
|
|
2462
|
+
const content = readMd('.mindforge/integrations/connection-manager.md');
|
|
2463
|
+
['available', 'unconfigured', 'invalid_credentials', 'unreachable', 'rate_limited'].forEach(s => {
|
|
2464
|
+
assert.ok(content.includes(s), `Missing availability state: ${s}`);
|
|
2465
|
+
});
|
|
2466
|
+
});
|
|
2467
|
+
|
|
2468
|
+
test('connection-manager has credential safety rule', () => {
|
|
2469
|
+
const content = readMd('.mindforge/integrations/connection-manager.md');
|
|
2470
|
+
assert.ok(content.includes('Never store credentials'), 'Missing credential safety rule');
|
|
2471
|
+
});
|
|
2472
|
+
|
|
2473
|
+
test('connection-manager defines integration_action AUDIT schema', () => {
|
|
2474
|
+
const content = readMd('.mindforge/integrations/connection-manager.md');
|
|
2475
|
+
assert.ok(content.includes('integration_action'), 'Missing integration_action AUDIT event');
|
|
2476
|
+
});
|
|
2477
|
+
|
|
2478
|
+
console.log('\nJira integration:');
|
|
2479
|
+
|
|
2480
|
+
test('jira.md uses REST API v3', () => {
|
|
2481
|
+
const content = readMd('.mindforge/integrations/jira.md');
|
|
2482
|
+
assert.ok(content.includes('/rest/api/3/') || content.includes('api/3'), 'Should use Jira API v3');
|
|
2483
|
+
});
|
|
2484
|
+
|
|
2485
|
+
test('jira.md has jira-sync.json schema', () => {
|
|
2486
|
+
const content = readMd('.mindforge/integrations/jira.md');
|
|
2487
|
+
assert.ok(content.includes('jira-sync.json'), 'Missing jira-sync.json state file');
|
|
2488
|
+
assert.ok(content.includes('phase_mappings'), 'Missing phase_mappings in sync schema');
|
|
2489
|
+
});
|
|
2490
|
+
|
|
2491
|
+
test('jira.md has conflict handling (no destructive overwrite)', () => {
|
|
2492
|
+
const content = readMd('.mindforge/integrations/jira.md');
|
|
2493
|
+
assert.ok(
|
|
2494
|
+
content.includes('manual Jira') || content.includes('manual changes'),
|
|
2495
|
+
'Jira spec should handle manual Jira changes without overwriting'
|
|
2496
|
+
);
|
|
2497
|
+
});
|
|
2498
|
+
|
|
2499
|
+
console.log('\nSlack integration:');
|
|
2500
|
+
|
|
2501
|
+
test('slack.md defines notification triggers', () => {
|
|
2502
|
+
const content = readMd('.mindforge/integrations/slack.md');
|
|
2503
|
+
['phase_complete', 'security_finding', 'approval_needed', 'milestone_complete'].forEach(t => {
|
|
2504
|
+
assert.ok(content.includes(t), `Missing notification trigger: ${t}`);
|
|
2505
|
+
});
|
|
2506
|
+
});
|
|
2507
|
+
|
|
2508
|
+
test('slack.md has graceful degradation', () => {
|
|
2509
|
+
const content = readMd('.mindforge/integrations/slack.md');
|
|
2510
|
+
assert.ok(
|
|
2511
|
+
content.includes('unconfigured') || content.includes('graceful'),
|
|
2512
|
+
'Slack should degrade gracefully when not configured'
|
|
2513
|
+
);
|
|
2514
|
+
});
|
|
2515
|
+
|
|
2516
|
+
test('slack.md does NOT notify on routine task completions', () => {
|
|
2517
|
+
const content = readMd('.mindforge/integrations/slack.md');
|
|
2518
|
+
assert.ok(
|
|
2519
|
+
content.includes('task_completed') && content.includes('No'),
|
|
2520
|
+
'Should explicitly state task_completed does not trigger Slack notification'
|
|
2521
|
+
);
|
|
2522
|
+
});
|
|
2523
|
+
|
|
2524
|
+
console.log('\nGitHub integration:');
|
|
2525
|
+
|
|
2526
|
+
test('github.md has PR template file path', () => {
|
|
2527
|
+
const content = readMd('.mindforge/integrations/github.md');
|
|
2528
|
+
assert.ok(content.includes('pull_request_template.md'), 'Should reference PR template');
|
|
2529
|
+
});
|
|
2530
|
+
|
|
2531
|
+
test('github.md has branch protection pre-flight check', () => {
|
|
2532
|
+
const content = readMd('.mindforge/integrations/github.md');
|
|
2533
|
+
assert.ok(
|
|
2534
|
+
content.includes('branch protection') || content.includes('pre-flight'),
|
|
2535
|
+
'Should check branch protection before creating PR'
|
|
2536
|
+
);
|
|
2537
|
+
});
|
|
2538
|
+
|
|
2539
|
+
console.log('\nIntegrations config:');
|
|
2540
|
+
|
|
2541
|
+
test('INTEGRATIONS-CONFIG.md exists', () => {
|
|
2542
|
+
assert.ok(fs.existsSync('.mindforge/org/integrations/INTEGRATIONS-CONFIG.md'));
|
|
2543
|
+
});
|
|
2544
|
+
|
|
2545
|
+
test('INTEGRATIONS-CONFIG.md has no credential values', () => {
|
|
2546
|
+
const content = readMd('.mindforge/org/integrations/INTEGRATIONS-CONFIG.md');
|
|
2547
|
+
// Should not contain actual tokens (only placeholder references)
|
|
2548
|
+
const credentialPattern = /=\s*(xox[pb]-[a-zA-Z0-9-]+|ghp_[a-zA-Z0-9]+|glpat-[a-zA-Z0-9]+)/;
|
|
2549
|
+
assert.ok(!credentialPattern.test(content), 'Config file should not contain actual API tokens');
|
|
2550
|
+
});
|
|
2551
|
+
|
|
2552
|
+
console.log('\nNew commands (21 total):');
|
|
2553
|
+
|
|
2554
|
+
const day4Commands = ['audit','milestone','complete-milestone','approve','sync-jira','sync-confluence'];
|
|
2555
|
+
const allExpectedCommands = [
|
|
2556
|
+
'help','init-project','plan-phase','execute-phase','verify-phase','ship',
|
|
2557
|
+
'next','quick','status','debug',
|
|
2558
|
+
'skills','review','security-scan','map-codebase','discuss-phase',
|
|
2559
|
+
...day4Commands
|
|
2560
|
+
];
|
|
2561
|
+
|
|
2562
|
+
test(`all ${allExpectedCommands.length} commands in .claude/commands/mindforge/`, () => {
|
|
2563
|
+
allExpectedCommands.forEach(cmd => {
|
|
2564
|
+
assert.ok(
|
|
2565
|
+
fs.existsSync(`.claude/commands/mindforge/${cmd}.md`),
|
|
2566
|
+
`Missing: .claude/commands/mindforge/${cmd}.md`
|
|
2567
|
+
);
|
|
2568
|
+
});
|
|
2569
|
+
});
|
|
2570
|
+
|
|
2571
|
+
test(`all ${allExpectedCommands.length} commands mirrored to .agent/mindforge/`, () => {
|
|
2572
|
+
allExpectedCommands.forEach(cmd => {
|
|
2573
|
+
assert.ok(
|
|
2574
|
+
fs.existsSync(`.agent/mindforge/${cmd}.md`),
|
|
2575
|
+
`Missing: .agent/mindforge/${cmd}.md`
|
|
2576
|
+
);
|
|
2577
|
+
});
|
|
2578
|
+
});
|
|
2579
|
+
|
|
2580
|
+
console.log(`\n${'─'.repeat(50)}`);
|
|
2581
|
+
console.log(`Results: ${passed} passed, ${failed} failed`);
|
|
2582
|
+
if (failed > 0) { console.error(`\n❌ ${failed} test(s) failed.\n`); process.exit(1); }
|
|
2583
|
+
else { console.log(`\n✅ All integration tests passed.\n`); }
|
|
2584
|
+
```
|
|
2585
|
+
|
|
2586
|
+
---
|
|
2587
|
+
|
|
2588
|
+
### `tests/governance.test.js`
|
|
2589
|
+
|
|
2590
|
+
```javascript
|
|
2591
|
+
/**
|
|
2592
|
+
* MindForge Day 4 — Governance Tests
|
|
2593
|
+
* Run: node tests/governance.test.js
|
|
2594
|
+
*/
|
|
2595
|
+
|
|
2596
|
+
const fs = require('fs');
|
|
2597
|
+
const path = require('path');
|
|
2598
|
+
const assert = require('assert');
|
|
2599
|
+
|
|
2600
|
+
let passed = 0;
|
|
2601
|
+
let failed = 0;
|
|
2602
|
+
|
|
2603
|
+
function test(name, fn) {
|
|
2604
|
+
try { fn(); console.log(` ✅ ${name}`); passed++; }
|
|
2605
|
+
catch (err) { console.error(` ❌ ${name}\n ${err.message}`); failed++; }
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
function readMd(p) { return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : ''; }
|
|
2609
|
+
|
|
2610
|
+
// ── Change classifier simulation ──────────────────────────────────────────────
|
|
2611
|
+
function classifyChange(files, hasNewFeatureCommit = false, dependencyAdded = false) {
|
|
2612
|
+
const tier3Paths = ['auth/', 'security/', 'payment/', 'billing/', 'privacy/'];
|
|
2613
|
+
const tier3Files = ['session.ts', 'login.ts', 'token.ts', 'password.ts', 'credentials.ts'];
|
|
2614
|
+
const tier3Code = ['bcrypt', 'argon2', 'jwt.sign', 'jwt.verify', 'stripe.'];
|
|
2615
|
+
|
|
2616
|
+
// Tier 3 check
|
|
2617
|
+
for (const file of files) {
|
|
2618
|
+
if (tier3Paths.some(p => file.includes(p))) return 3;
|
|
2619
|
+
if (tier3Files.some(f => file.endsWith(f))) return 3;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
// Tier 2 check
|
|
2623
|
+
if (hasNewFeatureCommit) return 2;
|
|
2624
|
+
if (dependencyAdded) return 2;
|
|
2625
|
+
if (files.length > 10) return 2;
|
|
2626
|
+
|
|
2627
|
+
return 1;
|
|
2628
|
+
}
|
|
2629
|
+
|
|
2630
|
+
// ── Approval schema validator ──────────────────────────────────────────────────
|
|
2631
|
+
function validateApprovalSchema(obj) {
|
|
2632
|
+
const required = [
|
|
2633
|
+
'schema_version', 'id', 'tier', 'status', 'requested_at',
|
|
2634
|
+
'expires_at', 'requester', 'approver', 'change_description',
|
|
2635
|
+
'_warning'
|
|
2636
|
+
];
|
|
2637
|
+
const missing = required.filter(f => obj[f] === undefined);
|
|
2638
|
+
if (missing.length > 0) throw new Error(`Missing fields: ${missing.join(', ')}`);
|
|
2639
|
+
if (!['pending','approved','rejected','expired'].includes(obj.status)) {
|
|
2640
|
+
throw new Error(`Invalid status: ${obj.status}`);
|
|
2641
|
+
}
|
|
2642
|
+
if (![1,2,3].includes(obj.tier)) throw new Error(`Invalid tier: ${obj.tier}`);
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
// ── Tests ─────────────────────────────────────────────────────────────────────
|
|
2646
|
+
console.log('\nMindForge Day 4 — Governance Tests\n');
|
|
2647
|
+
|
|
2648
|
+
console.log('Governance engine files:');
|
|
2649
|
+
['approval-workflow.md','change-classifier.md','compliance-gates.md','GOVERNANCE-CONFIG.md'].forEach(f => {
|
|
2650
|
+
test(`${f} exists`, () => assert.ok(
|
|
2651
|
+
fs.existsSync(`.mindforge/governance/${f}`),
|
|
2652
|
+
`Missing: .mindforge/governance/${f}`
|
|
2653
|
+
));
|
|
2654
|
+
});
|
|
2655
|
+
|
|
2656
|
+
console.log('\nChange classifier logic:');
|
|
2657
|
+
|
|
2658
|
+
test('files in auth/ are classified as Tier 3', () => {
|
|
2659
|
+
assert.strictEqual(classifyChange(['src/auth/session.ts']), 3);
|
|
2660
|
+
});
|
|
2661
|
+
|
|
2662
|
+
test('login.ts is classified as Tier 3 regardless of directory', () => {
|
|
2663
|
+
assert.strictEqual(classifyChange(['src/features/user/login.ts']), 3);
|
|
2664
|
+
});
|
|
2665
|
+
|
|
2666
|
+
test('payment/ path is classified as Tier 3', () => {
|
|
2667
|
+
assert.strictEqual(classifyChange(['src/services/payment/stripe.ts']), 3);
|
|
2668
|
+
});
|
|
2669
|
+
|
|
2670
|
+
test('new feature commit (feat:) is classified as Tier 2', () => {
|
|
2671
|
+
assert.strictEqual(classifyChange(['src/api/users.ts'], true), 2);
|
|
2672
|
+
});
|
|
2673
|
+
|
|
2674
|
+
test('dependency addition is classified as Tier 2', () => {
|
|
2675
|
+
assert.strictEqual(classifyChange(['src/utils/helper.ts'], false, true), 2);
|
|
2676
|
+
});
|
|
2677
|
+
|
|
2678
|
+
test('more than 10 files changed is classified as Tier 2', () => {
|
|
2679
|
+
const manyFiles = Array.from({ length: 11 }, (_, i) => `src/component-${i}.ts`);
|
|
2680
|
+
assert.strictEqual(classifyChange(manyFiles), 2);
|
|
2681
|
+
});
|
|
2682
|
+
|
|
2683
|
+
test('documentation changes are classified as Tier 1', () => {
|
|
2684
|
+
assert.strictEqual(classifyChange(['docs/README.md', 'CHANGELOG.md']), 1);
|
|
2685
|
+
});
|
|
2686
|
+
|
|
2687
|
+
test('bug fix to non-auth code is Tier 1', () => {
|
|
2688
|
+
assert.strictEqual(classifyChange(['src/utils/format-date.ts']), 1);
|
|
2689
|
+
});
|
|
2690
|
+
|
|
2691
|
+
test('Tier 3 takes priority over Tier 2', () => {
|
|
2692
|
+
// Even with > 10 files AND a feat commit, auth path = Tier 3
|
|
2693
|
+
const files = ['src/auth/login.ts', ...Array.from({ length: 11 }, (_, i) => `src/component-${i}.ts`)];
|
|
2694
|
+
assert.strictEqual(classifyChange(files, true), 3);
|
|
2695
|
+
});
|
|
2696
|
+
|
|
2697
|
+
console.log('\nApproval schema validation:');
|
|
2698
|
+
|
|
2699
|
+
test('valid Tier 2 approval schema passes validation', () => {
|
|
2700
|
+
const approval = {
|
|
2701
|
+
schema_version: '1.0.0',
|
|
2702
|
+
id: '550e8400-e29b-41d4-a716-446655440000',
|
|
2703
|
+
tier: 2,
|
|
2704
|
+
status: 'pending',
|
|
2705
|
+
requested_at: new Date().toISOString(),
|
|
2706
|
+
expires_at: new Date(Date.now() + 48*60*60*1000).toISOString(),
|
|
2707
|
+
requester: 'mindforge-orchestrator',
|
|
2708
|
+
approver: 'john-company-com',
|
|
2709
|
+
change_description: 'Add user RBAC model',
|
|
2710
|
+
_warning: 'Never store secrets'
|
|
2711
|
+
};
|
|
2712
|
+
assert.doesNotThrow(() => validateApprovalSchema(approval));
|
|
2713
|
+
});
|
|
2714
|
+
|
|
2715
|
+
test('approval with invalid status fails validation', () => {
|
|
2716
|
+
const approval = {
|
|
2717
|
+
schema_version: '1.0.0', id: 'uuid', tier: 2, status: 'waiting',
|
|
2718
|
+
requested_at: 'now', expires_at: 'later', requester: 'agent',
|
|
2719
|
+
approver: 'person', change_description: 'desc', _warning: 'warn'
|
|
2720
|
+
};
|
|
2721
|
+
assert.throws(() => validateApprovalSchema(approval), /Invalid status/);
|
|
2722
|
+
});
|
|
2723
|
+
|
|
2724
|
+
test('approval with invalid tier fails validation', () => {
|
|
2725
|
+
const approval = {
|
|
2726
|
+
schema_version: '1.0.0', id: 'uuid', tier: 4, status: 'pending',
|
|
2727
|
+
requested_at: 'now', expires_at: 'later', requester: 'agent',
|
|
2728
|
+
approver: 'person', change_description: 'desc', _warning: 'warn'
|
|
2729
|
+
};
|
|
2730
|
+
assert.throws(() => validateApprovalSchema(approval), /Invalid tier/);
|
|
2731
|
+
});
|
|
2732
|
+
|
|
2733
|
+
console.log('\nCompliance gates:');
|
|
2734
|
+
|
|
2735
|
+
test('compliance-gates.md defines all 5 gates', () => {
|
|
2736
|
+
const content = readMd('.mindforge/governance/compliance-gates.md');
|
|
2737
|
+
['Gate 1', 'Gate 2', 'Gate 3', 'Gate 4', 'Gate 5'].forEach(g => {
|
|
2738
|
+
assert.ok(content.includes(g), `Missing ${g}`);
|
|
2739
|
+
});
|
|
2740
|
+
});
|
|
2741
|
+
|
|
2742
|
+
test('Gate 3 (no secrets) cannot be overridden', () => {
|
|
2743
|
+
const content = readMd('.mindforge/governance/compliance-gates.md');
|
|
2744
|
+
const gate3Section = content.split('Gate 4')[0].split('Gate 3')[1] || '';
|
|
2745
|
+
assert.ok(
|
|
2746
|
+
gate3Section.includes('Not possible') || gate3Section.includes('not possible'),
|
|
2747
|
+
'Gate 3 should explicitly state it cannot be overridden'
|
|
2748
|
+
);
|
|
2749
|
+
});
|
|
2750
|
+
|
|
2751
|
+
test('compliance-gates.md defines gate execution order', () => {
|
|
2752
|
+
const content = readMd('.mindforge/governance/compliance-gates.md');
|
|
2753
|
+
assert.ok(content.includes('Gate execution') || content.includes('execution order'),
|
|
2754
|
+
'Should define gate execution order'
|
|
2755
|
+
);
|
|
2756
|
+
});
|
|
2757
|
+
|
|
2758
|
+
console.log('\nMulti-developer HANDOFF:');
|
|
2759
|
+
|
|
2760
|
+
test('multi-handoff.md defines per-developer file naming', () => {
|
|
2761
|
+
const content = readMd('.mindforge/team/multi-handoff.md');
|
|
2762
|
+
assert.ok(content.includes('HANDOFF-[dev-id]') || content.includes('dev_id'), 'Should define per-developer HANDOFF naming');
|
|
2763
|
+
});
|
|
2764
|
+
|
|
2765
|
+
test('multi-handoff.md has conflict detection', () => {
|
|
2766
|
+
const content = readMd('.mindforge/team/multi-handoff.md');
|
|
2767
|
+
assert.ok(content.includes('conflict') || content.includes('overlap'), 'Should have file conflict detection');
|
|
2768
|
+
});
|
|
2769
|
+
|
|
2770
|
+
test('handoffs directory exists', () => {
|
|
2771
|
+
// Directory may not exist until first team use — check it gets created
|
|
2772
|
+
const dirOrPlaceholder =
|
|
2773
|
+
fs.existsSync('.planning/handoffs') ||
|
|
2774
|
+
readMd('.mindforge/team/multi-handoff.md').includes('handoffs/');
|
|
2775
|
+
assert.ok(dirOrPlaceholder, 'Handoffs directory or reference should exist');
|
|
2776
|
+
});
|
|
2777
|
+
|
|
2778
|
+
console.log('\nMilestone system:');
|
|
2779
|
+
|
|
2780
|
+
test('milestones directory or reference exists', () => {
|
|
2781
|
+
const milestoneCmd = readMd('.claude/commands/mindforge/milestone.md');
|
|
2782
|
+
assert.ok(milestoneCmd.includes('milestones/') || milestoneCmd.includes('.planning/milestones'),
|
|
2783
|
+
'Milestone command should reference milestones directory'
|
|
2784
|
+
);
|
|
2785
|
+
});
|
|
2786
|
+
|
|
2787
|
+
test('complete-milestone runs final security scan', () => {
|
|
2788
|
+
const content = readMd('.claude/commands/mindforge/complete-milestone.md');
|
|
2789
|
+
assert.ok(content.includes('security-scan') || content.includes('security scan'),
|
|
2790
|
+
'complete-milestone should run a final security scan'
|
|
2791
|
+
);
|
|
2792
|
+
});
|
|
2793
|
+
|
|
2794
|
+
test('complete-milestone creates a release tag', () => {
|
|
2795
|
+
const content = readMd('.claude/commands/mindforge/complete-milestone.md');
|
|
2796
|
+
assert.ok(content.includes('git tag') || content.includes('release tag'),
|
|
2797
|
+
'complete-milestone should create a release tag'
|
|
2798
|
+
);
|
|
2799
|
+
});
|
|
2800
|
+
|
|
2801
|
+
console.log(`\n${'─'.repeat(50)}`);
|
|
2802
|
+
console.log(`Results: ${passed} passed, ${failed} failed`);
|
|
2803
|
+
if (failed > 0) { console.error(`\n❌ ${failed} test(s) failed.\n`); process.exit(1); }
|
|
2804
|
+
else { console.log(`\n✅ All governance tests passed.\n`); }
|
|
2805
|
+
```
|
|
2806
|
+
|
|
2807
|
+
**Commit:**
|
|
2808
|
+
```bash
|
|
2809
|
+
git add tests/integrations.test.js tests/governance.test.js
|
|
2810
|
+
git commit -m "test(day4): add integration and governance test suites"
|
|
2811
|
+
```
|
|
2812
|
+
|
|
2813
|
+
---
|
|
2814
|
+
|
|
2815
|
+
## TASK 14 — Run full test battery and verify Day 4
|
|
2816
|
+
|
|
2817
|
+
```bash
|
|
2818
|
+
node tests/install.test.js && echo "✅ install"
|
|
2819
|
+
node tests/wave-engine.test.js && echo "✅ wave-engine"
|
|
2820
|
+
node tests/audit.test.js && echo "✅ audit"
|
|
2821
|
+
node tests/compaction.test.js && echo "✅ compaction"
|
|
2822
|
+
node tests/skills-platform.test.js && echo "✅ skills-platform"
|
|
2823
|
+
node tests/integrations.test.js && echo "✅ integrations"
|
|
2824
|
+
node tests/governance.test.js && echo "✅ governance"
|
|
2825
|
+
```
|
|
2826
|
+
|
|
2827
|
+
**Final Day 4 commit:**
|
|
2828
|
+
```bash
|
|
2829
|
+
git add .
|
|
2830
|
+
git commit -m "feat(day4): complete Day 4 enterprise integrations and governance layer"
|
|
2831
|
+
git push origin feat/mindforge-enterprise-integrations
|
|
2832
|
+
```
|
|
2833
|
+
|
|
2834
|
+
---
|
|
2835
|
+
|
|
2836
|
+
## DAY 4 VERIFY — complete before pushing
|
|
2837
|
+
|
|
2838
|
+
```bash
|
|
2839
|
+
# 1. All 6 integration files exist
|
|
2840
|
+
ls .mindforge/integrations/ | wc -l # Expected: 6
|
|
2841
|
+
|
|
2842
|
+
# 2. All 4 governance files exist
|
|
2843
|
+
ls .mindforge/governance/ | wc -l # Expected: 4
|
|
2844
|
+
|
|
2845
|
+
# 3. All 21 commands in both runtimes
|
|
2846
|
+
ls .claude/commands/mindforge/ | wc -l # Expected: 21
|
|
2847
|
+
ls .agent/mindforge/ | wc -l # Expected: 21
|
|
2848
|
+
diff <(ls .claude/commands/mindforge/ | sort) <(ls .agent/mindforge/ | sort)
|
|
2849
|
+
# Expected: no output
|
|
2850
|
+
|
|
2851
|
+
# 4. All 7 test suites pass
|
|
2852
|
+
node tests/install.test.js && node tests/wave-engine.test.js && \
|
|
2853
|
+
node tests/audit.test.js && node tests/compaction.test.js && \
|
|
2854
|
+
node tests/skills-platform.test.js && node tests/integrations.test.js && \
|
|
2855
|
+
node tests/governance.test.js
|
|
2856
|
+
|
|
2857
|
+
# 5. No credentials in any config file
|
|
2858
|
+
grep -rE "xox[pb]-[a-zA-Z0-9-]+|ghp_[a-zA-Z0-9]+|glpat-" \
|
|
2859
|
+
--include="*.md" --include="*.json" \
|
|
2860
|
+
--exclude-dir=node_modules --exclude-dir=.git . 2>/dev/null
|
|
2861
|
+
# Expected: no output
|
|
2862
|
+
|
|
2863
|
+
# 6. ADRs — 8+ total
|
|
2864
|
+
ls .planning/decisions/*.md | wc -l # Expected: >= 8
|
|
2865
|
+
|
|
2866
|
+
# 7. Git log clean
|
|
2867
|
+
git log --oneline | head -25
|
|
2868
|
+
# Expected: ~14 clean commits from Day 4
|
|
2869
|
+
```
|
|
2870
|
+
|
|
2871
|
+
---
|
|
2872
|
+
|
|
2873
|
+
**Branch:** `feat/mindforge-enterprise-integrations`
|
|
2874
|
+
**Day 4 implementation complete. Proceed to DAY4-REVIEW.md.**
|