all-hands-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.allhands/README.md +75 -0
- package/.allhands/agents/compounder.yaml +15 -0
- package/.allhands/agents/coordinator.yaml +17 -0
- package/.allhands/agents/documentor.yaml +15 -0
- package/.allhands/agents/e2e-test-planner.yaml +17 -0
- package/.allhands/agents/emergent.yaml +22 -0
- package/.allhands/agents/executor.yaml +14 -0
- package/.allhands/agents/ideation.yaml +11 -0
- package/.allhands/agents/initiative-steering.yaml +19 -0
- package/.allhands/agents/judge.yaml +13 -0
- package/.allhands/agents/planner.yaml +19 -0
- package/.allhands/agents/pr-reviewer.yaml +15 -0
- package/.allhands/docs.json +5 -0
- package/.allhands/docs.local.json +26 -0
- package/.allhands/flows/COMPOUNDING.md +203 -0
- package/.allhands/flows/COORDINATION.md +89 -0
- package/.allhands/flows/CORE.md +87 -0
- package/.allhands/flows/DOCUMENTATION.md +218 -0
- package/.allhands/flows/E2E_TEST_PLAN_BUILDING.md +140 -0
- package/.allhands/flows/EMERGENT_PLANNING.md +57 -0
- package/.allhands/flows/IDEATION_SCOPING.md +154 -0
- package/.allhands/flows/INITIATIVE_STEERING.md +110 -0
- package/.allhands/flows/JUDGE_REVIEWING.md +79 -0
- package/.allhands/flows/PROMPT_TASK_EXECUTION.md +68 -0
- package/.allhands/flows/PR_REVIEWING.md +43 -0
- package/.allhands/flows/SPEC_PLANNING.md +216 -0
- package/.allhands/flows/harness/WRITING_HARNESS_FLOWS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_KNOWLEDGE.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_ORCHESTRATION.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_SKILLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_TOOLS.md +27 -0
- package/.allhands/flows/harness/WRITING_HARNESS_VALIDATION_TOOLING.md +27 -0
- package/.allhands/flows/shared/CODEBASE_UNDERSTANDING.md +72 -0
- package/.allhands/flows/shared/CREATE_HARNESS_SPEC.md +48 -0
- package/.allhands/flows/shared/CREATE_SPEC.md +41 -0
- package/.allhands/flows/shared/CREATE_VALIDATION_TOOLING_SPEC.md +70 -0
- package/.allhands/flows/shared/DOCUMENTATION_DISCOVERY.md +123 -0
- package/.allhands/flows/shared/DOCUMENTATION_WRITER.md +101 -0
- package/.allhands/flows/shared/EMERGENT_REFINEMENT_ANALYSIS.md +76 -0
- package/.allhands/flows/shared/EXTERNAL_TECH_GUIDANCE.md +97 -0
- package/.allhands/flows/shared/IDEATION_CODEBASE_GROUNDING.md +49 -0
- package/.allhands/flows/shared/PLAN_DEEPENING.md +152 -0
- package/.allhands/flows/shared/PROMPT_TASKS_CURATION.md +113 -0
- package/.allhands/flows/shared/PROMPT_VALIDATION_REVIEW.MD +99 -0
- package/.allhands/flows/shared/QUICK_PREMORTEM.md +70 -0
- package/.allhands/flows/shared/RESEARCH_GUIDANCE.md +38 -0
- package/.allhands/flows/shared/REVIEW_OPTIONS_BREAKDOWN.md +68 -0
- package/.allhands/flows/shared/SKILL_EXTRACTION.md +84 -0
- package/.allhands/flows/shared/SPEC_FLOW_ANALYSIS.md +119 -0
- package/.allhands/flows/shared/TDD_WORKFLOW.md +109 -0
- package/.allhands/flows/shared/UTILIZE_VALIDATION_TOOLING.md +84 -0
- package/.allhands/flows/shared/WRITING_HARNESS_FLOWS.md +11 -0
- package/.allhands/flows/shared/WRITING_HARNESS_MCP_TOOLS.md +84 -0
- package/.allhands/flows/shared/jury/ARCHITECTURE_REVIEW.md +91 -0
- package/.allhands/flows/shared/jury/BEST_PRACTICES_REVIEW.md +80 -0
- package/.allhands/flows/shared/jury/CLAIM_VERIFICATION_REVIEW.md +101 -0
- package/.allhands/flows/shared/jury/EXPECTATIONS_FIT_REVIEW.md +78 -0
- package/.allhands/flows/shared/jury/MAINTAINABILITY_REVIEW.md +110 -0
- package/.allhands/flows/shared/jury/PROMPTS_EXPECTATIONS_FIT.md +74 -0
- package/.allhands/flows/shared/jury/PROMPTS_FLOW_ANALYSIS.md +92 -0
- package/.allhands/flows/shared/jury/PROMPTS_YAGNI.md +78 -0
- package/.allhands/flows/shared/jury/PROMPT_PREMORTEM.md +125 -0
- package/.allhands/flows/shared/jury/SECURITY_REVIEW.md +86 -0
- package/.allhands/flows/shared/jury/YAGNI_REVIEW.md +82 -0
- package/.allhands/flows/wip/DEBUG_INVESTIGATION.md +162 -0
- package/.allhands/flows/wip/MEMORY_RECALL.md +62 -0
- package/.allhands/harness/ah +131 -0
- package/.allhands/harness/package-lock.json +5292 -0
- package/.allhands/harness/package.json +52 -0
- package/.allhands/harness/src/__tests__/e2e/commands.test.ts +307 -0
- package/.allhands/harness/src/__tests__/e2e/event-loop.test.ts +539 -0
- package/.allhands/harness/src/__tests__/e2e/hooks.test.ts +427 -0
- package/.allhands/harness/src/__tests__/e2e/new-initiative-routing.test.ts +137 -0
- package/.allhands/harness/src/__tests__/e2e/run-e2e.ts +109 -0
- package/.allhands/harness/src/__tests__/e2e/specs-type.test.ts +210 -0
- package/.allhands/harness/src/__tests__/e2e/validation-hooks.test.ts +669 -0
- package/.allhands/harness/src/__tests__/e2e/validation-path-consistency.test.ts +354 -0
- package/.allhands/harness/src/__tests__/e2e/validation.test.ts +528 -0
- package/.allhands/harness/src/__tests__/harness/assertions.ts +318 -0
- package/.allhands/harness/src/__tests__/harness/cli-runner.ts +359 -0
- package/.allhands/harness/src/__tests__/harness/fixture.ts +384 -0
- package/.allhands/harness/src/__tests__/harness/hook-runner.ts +411 -0
- package/.allhands/harness/src/__tests__/harness/index.ts +122 -0
- package/.allhands/harness/src/cli.ts +36 -0
- package/.allhands/harness/src/commands/complexity.ts +177 -0
- package/.allhands/harness/src/commands/context7.ts +202 -0
- package/.allhands/harness/src/commands/docs.ts +557 -0
- package/.allhands/harness/src/commands/hooks.ts +24 -0
- package/.allhands/harness/src/commands/index.ts +51 -0
- package/.allhands/harness/src/commands/knowledge.ts +382 -0
- package/.allhands/harness/src/commands/memories.ts +302 -0
- package/.allhands/harness/src/commands/notify.ts +61 -0
- package/.allhands/harness/src/commands/oracle.ts +158 -0
- package/.allhands/harness/src/commands/perplexity.ts +220 -0
- package/.allhands/harness/src/commands/planning.ts +245 -0
- package/.allhands/harness/src/commands/schema.ts +73 -0
- package/.allhands/harness/src/commands/skills.ts +128 -0
- package/.allhands/harness/src/commands/solutions.ts +353 -0
- package/.allhands/harness/src/commands/spawn.ts +158 -0
- package/.allhands/harness/src/commands/specs.ts +532 -0
- package/.allhands/harness/src/commands/tavily.ts +226 -0
- package/.allhands/harness/src/commands/tools.ts +579 -0
- package/.allhands/harness/src/commands/trace.ts +327 -0
- package/.allhands/harness/src/commands/tui.ts +960 -0
- package/.allhands/harness/src/commands/validate.ts +143 -0
- package/.allhands/harness/src/commands/validation-tools.ts +108 -0
- package/.allhands/harness/src/hooks/context.ts +1442 -0
- package/.allhands/harness/src/hooks/enforcement.ts +170 -0
- package/.allhands/harness/src/hooks/index.ts +54 -0
- package/.allhands/harness/src/hooks/lifecycle.ts +229 -0
- package/.allhands/harness/src/hooks/notification.ts +104 -0
- package/.allhands/harness/src/hooks/observability.ts +551 -0
- package/.allhands/harness/src/hooks/session.ts +88 -0
- package/.allhands/harness/src/hooks/shared.ts +815 -0
- package/.allhands/harness/src/hooks/transcript-parser.ts +208 -0
- package/.allhands/harness/src/hooks/validation.ts +617 -0
- package/.allhands/harness/src/lib/__tests__/ctags.test.ts +244 -0
- package/.allhands/harness/src/lib/__tests__/docs-validation.test.ts +344 -0
- package/.allhands/harness/src/lib/__tests__/mcp-runtime.test.ts +190 -0
- package/.allhands/harness/src/lib/__tests__/schema.test.ts +861 -0
- package/.allhands/harness/src/lib/base-command.ts +198 -0
- package/.allhands/harness/src/lib/cli-daemon.ts +343 -0
- package/.allhands/harness/src/lib/compaction.ts +313 -0
- package/.allhands/harness/src/lib/ctags.ts +497 -0
- package/.allhands/harness/src/lib/docs-validation.ts +907 -0
- package/.allhands/harness/src/lib/event-loop.ts +662 -0
- package/.allhands/harness/src/lib/flows.ts +155 -0
- package/.allhands/harness/src/lib/git.ts +276 -0
- package/.allhands/harness/src/lib/knowledge-worker.ts +72 -0
- package/.allhands/harness/src/lib/knowledge.ts +810 -0
- package/.allhands/harness/src/lib/llm.ts +255 -0
- package/.allhands/harness/src/lib/mcp-client.ts +432 -0
- package/.allhands/harness/src/lib/mcp-daemon.ts +486 -0
- package/.allhands/harness/src/lib/mcp-runtime.ts +418 -0
- package/.allhands/harness/src/lib/notification.ts +115 -0
- package/.allhands/harness/src/lib/opencode/index.ts +70 -0
- package/.allhands/harness/src/lib/opencode/profiles.ts +300 -0
- package/.allhands/harness/src/lib/opencode/prompts/codesearch.md +98 -0
- package/.allhands/harness/src/lib/opencode/prompts/knowledge-aggregator.md +67 -0
- package/.allhands/harness/src/lib/opencode/runner.ts +281 -0
- package/.allhands/harness/src/lib/oracle.ts +926 -0
- package/.allhands/harness/src/lib/planning-utils.ts +150 -0
- package/.allhands/harness/src/lib/planning.ts +605 -0
- package/.allhands/harness/src/lib/pr-review.ts +225 -0
- package/.allhands/harness/src/lib/prompts.ts +522 -0
- package/.allhands/harness/src/lib/schema.ts +418 -0
- package/.allhands/harness/src/lib/schemas/agent-profile.ts +141 -0
- package/.allhands/harness/src/lib/schemas/template-vars.ts +138 -0
- package/.allhands/harness/src/lib/session.ts +164 -0
- package/.allhands/harness/src/lib/specs.ts +348 -0
- package/.allhands/harness/src/lib/tldr.ts +829 -0
- package/.allhands/harness/src/lib/tmux.ts +1051 -0
- package/.allhands/harness/src/lib/trace-store.ts +714 -0
- package/.allhands/harness/src/mcp/__tests__/index.test.ts +46 -0
- package/.allhands/harness/src/mcp/_template.ts +47 -0
- package/.allhands/harness/src/mcp/filesystem.ts +33 -0
- package/.allhands/harness/src/mcp/index.ts +69 -0
- package/.allhands/harness/src/mcp/playwright.ts +34 -0
- package/.allhands/harness/src/mcp/xcodebuild.ts +29 -0
- package/.allhands/harness/src/schemas/docs.schema.json +44 -0
- package/.allhands/harness/src/schemas/settings.schema.json +214 -0
- package/.allhands/harness/src/tui/actions.ts +227 -0
- package/.allhands/harness/src/tui/file-viewer-modal.ts +270 -0
- package/.allhands/harness/src/tui/index.ts +1574 -0
- package/.allhands/harness/src/tui/modal.ts +232 -0
- package/.allhands/harness/src/tui/prompts-pane.ts +186 -0
- package/.allhands/harness/src/tui/status-pane.ts +434 -0
- package/.allhands/harness/tsconfig.json +22 -0
- package/.allhands/harness/vitest.config.ts +13 -0
- package/.allhands/pillars.md +33 -0
- package/.allhands/principles.md +88 -0
- package/.allhands/schemas/alignment.yaml +51 -0
- package/.allhands/schemas/documentation.yaml +10 -0
- package/.allhands/schemas/prompt.yaml +92 -0
- package/.allhands/schemas/skill.yaml +34 -0
- package/.allhands/schemas/solution.yaml +131 -0
- package/.allhands/schemas/spec.yaml +67 -0
- package/.allhands/schemas/validation-suite.yaml +49 -0
- package/.allhands/schemas/workflow.yaml +51 -0
- package/.allhands/settings.json +57 -0
- package/.allhands/skills/claude-code-patterns/SKILL.md +60 -0
- package/.allhands/skills/claude-code-patterns/docs/context-hygiene.md +19 -0
- package/.allhands/skills/harness-maintenance/SKILL.md +449 -0
- package/.allhands/skills/harness-maintenance/references/core-architecture.md +187 -0
- package/.allhands/skills/harness-maintenance/references/harness-skills.md +87 -0
- package/.allhands/skills/harness-maintenance/references/knowledge-compounding.md +78 -0
- package/.allhands/skills/harness-maintenance/references/tools-commands-mcp-hooks.md +115 -0
- package/.allhands/skills/harness-maintenance/references/validation-tooling.md +77 -0
- package/.allhands/skills/harness-maintenance/references/writing-flows.md +84 -0
- package/.allhands/validation/browser-automation.md +109 -0
- package/.allhands/validation/xcode-automation.md +195 -0
- package/.allhands/workflows/documentation.md +86 -0
- package/.allhands/workflows/investigation.md +81 -0
- package/.allhands/workflows/milestone.md +91 -0
- package/.allhands/workflows/optimization.md +85 -0
- package/.allhands/workflows/refactor.md +99 -0
- package/.allhands/workflows/triage.md +81 -0
- package/.claude/README.md +1 -0
- package/.claude/agents/explorer.md +10 -0
- package/.claude/agents/researcher.md +11 -0
- package/.claude/agents/task-runner.md +8 -0
- package/.claude/settings.json +231 -0
- package/.env.ai.example +7 -0
- package/.github/workflows/npm-publish.yml +69 -0
- package/.internal.json +45 -0
- package/.tldr/config.json +11 -0
- package/.tldrignore +90 -0
- package/CLAUDE.md +6 -0
- package/README.md +98 -0
- package/bin/sync-cli.js +7552 -0
- package/concerns.md +7 -0
- package/docs/README.md +41 -0
- package/docs/agents/README.md +24 -0
- package/docs/agents/agent-configuration-system.md +86 -0
- package/docs/agents/execution-agents.md +50 -0
- package/docs/agents/knowledge-agents.md +61 -0
- package/docs/agents/orchestration-agent.md +57 -0
- package/docs/agents/planning-agents.md +84 -0
- package/docs/agents/quality-review-agents.md +67 -0
- package/docs/agents/workflow-agent-orchestration.md +69 -0
- package/docs/flows/README.md +44 -0
- package/docs/flows/compounding.md +126 -0
- package/docs/flows/coordination.md +72 -0
- package/docs/flows/core-harness-integration.md +63 -0
- package/docs/flows/documentation-orchestration.md +98 -0
- package/docs/flows/e2e-test-plan-building.md +83 -0
- package/docs/flows/emergent-refinement.md +104 -0
- package/docs/flows/flow-authoring-and-mcp-tools.md +89 -0
- package/docs/flows/judge-reviewing.md +112 -0
- package/docs/flows/plan-deepening-and-research.md +107 -0
- package/docs/flows/plan-review-jury.md +114 -0
- package/docs/flows/pr-reviewing.md +54 -0
- package/docs/flows/prompt-task-execution.md +119 -0
- package/docs/flows/spec-planning.md +162 -0
- package/docs/flows/type-specific-scoping-flows.md +49 -0
- package/docs/flows/validation-and-skills-integration.md +145 -0
- package/docs/flows/wip/wip-flows.md +102 -0
- package/docs/harness/README.md +23 -0
- package/docs/harness/agent-profiles.md +84 -0
- package/docs/harness/cli/README.md +24 -0
- package/docs/harness/cli/cli-entry-and-command-discovery.md +91 -0
- package/docs/harness/cli/docs-command.md +87 -0
- package/docs/harness/cli/knowledge-command.md +91 -0
- package/docs/harness/cli/minor-cli-commands.md +65 -0
- package/docs/harness/cli/oracle-command.md +113 -0
- package/docs/harness/cli/planning-command.md +95 -0
- package/docs/harness/cli/schema-and-validation-commands.md +154 -0
- package/docs/harness/cli/search-commands.md +97 -0
- package/docs/harness/cli/spawn-command.md +136 -0
- package/docs/harness/cli/specs-command.md +102 -0
- package/docs/harness/cli/tools-command.md +122 -0
- package/docs/harness/cli/trace-command.md +122 -0
- package/docs/harness/cli-daemon.md +92 -0
- package/docs/harness/event-loop.md +184 -0
- package/docs/harness/hooks/README.md +15 -0
- package/docs/harness/hooks/context-hooks.md +96 -0
- package/docs/harness/hooks/lifecycle-and-observability-hooks.md +135 -0
- package/docs/harness/hooks/validation-hooks.md +97 -0
- package/docs/harness/test-harness.md +149 -0
- package/docs/harness/tui.md +176 -0
- package/docs/memories.md +20 -0
- package/docs/solutions/agentic-issues/premature-agent-deletion-tui-action-dependency-20260130.md +49 -0
- package/docs/solutions/agentic-issues/ref-anchor-scope-mismatch-skill-references-20260131.md +55 -0
- package/docs/solutions/agentic-issues/tautological-tests-routing-20260131.md +52 -0
- package/docs/solutions/integration_issue/blocktool-output-format-mismatch-hook-runner-20260130.md +52 -0
- package/docs/solutions/integration_issue/dual-validation-path-divergence-schema-20260130.md +66 -0
- package/docs/solutions/security-issues/unsanitized-domain-path-join-20260131.md +52 -0
- package/docs/solutions/test-failures/event-loop-mock-ordering-checkAgentWindows-20260130.md +63 -0
- package/docs/sync-cli/README.md +19 -0
- package/docs/sync-cli/cli-entrypoint-and-commands.md +39 -0
- package/docs/sync-cli/commands/README.md +11 -0
- package/docs/sync-cli/commands/pull-manifest-command.md +36 -0
- package/docs/sync-cli/commands/push-command.md +84 -0
- package/docs/sync-cli/commands/sync-command.md +71 -0
- package/docs/sync-cli/systems/README.md +14 -0
- package/docs/sync-cli/systems/git-and-github-integration.md +49 -0
- package/docs/sync-cli/systems/interactive-ui.md +43 -0
- package/docs/sync-cli/systems/manifest-and-distribution.md +51 -0
- package/docs/sync-cli/systems/path-resolution.md +42 -0
- package/package.json +46 -0
- package/scripts/install-shim.sh +40 -0
- package/scripts/pre-pack.sh +25 -0
- package/specs/harness-maintenance-skill.spec.md +138 -0
- package/specs/roadmap/git-spec-lifecycle-management.spec.md +113 -0
- package/specs/sync-init-flag.spec.md +117 -0
- package/specs/unified-workflow-orchestration.spec.md +250 -0
- package/specs/validation-tooling-practice.spec.md +98 -0
- package/specs/workflow-domain-configuration.spec.md +265 -0
- package/src/commands/pull-manifest.ts +31 -0
- package/src/commands/push.ts +344 -0
- package/src/commands/sync.ts +289 -0
- package/src/lib/constants.ts +10 -0
- package/src/lib/dotfiles.ts +36 -0
- package/src/lib/fs-utils.ts +18 -0
- package/src/lib/gh.ts +40 -0
- package/src/lib/git.ts +63 -0
- package/src/lib/gitignore.ts +167 -0
- package/src/lib/manifest.ts +121 -0
- package/src/lib/marker-sync.ts +39 -0
- package/src/lib/paths.ts +38 -0
- package/src/lib/target-lines.ts +66 -0
- package/src/lib/ui.ts +78 -0
- package/src/sync-cli.ts +120 -0
- package/target-lines.json +23 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workflow-domain-configuration
|
|
3
|
+
domain_name: infrastructure
|
|
4
|
+
type: milestone
|
|
5
|
+
status: completed
|
|
6
|
+
dependencies: []
|
|
7
|
+
branch: feature/workflow-domain-configuration
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Workflow Domain Configuration
|
|
11
|
+
|
|
12
|
+
## Motivation
|
|
13
|
+
|
|
14
|
+
The harness currently has domain-specific scoping logic scattered across six separate flow files (IDEATION_SESSION.md, INVESTIGATION_SCOPING.md, OPTIMIZATION_SCOPING.md, REFACTOR_SCOPING.md, DOCUMENTATION_SCOPING.md, TRIAGE_SCOPING.md). Each flow hardcodes its domain's interview questions, considerations, and output patterns. This creates three structural problems:
|
|
15
|
+
|
|
16
|
+
1. **Domain logic fragmentation** — Each scoping flow independently encodes what to ask and what to consider for its domain. Adding a new domain means creating a new flow file. Modifying domain considerations means finding the right flow file. There is no single source of truth for what makes each domain's workflow distinct.
|
|
17
|
+
|
|
18
|
+
2. **No mid-execution scope adjustment** — When an engineer discovers a need for investigation, refactoring, or optimization during an active milestone's execution, there is no structured way to inject that scope into the running initiative. The only options are: create a separate spec on a new branch (fragmenting the work), or use the coordinator for ad-hoc patching (no domain-specific structure). Neither preserves the initiative's coherence while adding structured new scope.
|
|
19
|
+
|
|
20
|
+
3. **Rigid flow-to-domain coupling** — The ideation flow, spec planning flow, and the needed adjustment flow all require domain-specific behavior, but that behavior is locked inside ideation-only scoping flows. Spec planning cannot leverage domain considerations for its constraint analysis. A mid-execution adjustment flow cannot ask domain-appropriate questions without reimplementing domain logic.
|
|
21
|
+
|
|
22
|
+
Engineer desires a **workflow domain configuration** model: centralized config files per domain consumed by three core flows (ideation scoping, spec planning, initiative steering), with each flow interpreting the domain config at its appropriate abstraction level.
|
|
23
|
+
|
|
24
|
+
## Goals
|
|
25
|
+
|
|
26
|
+
### 1. Workflow Domain Config Files
|
|
27
|
+
|
|
28
|
+
Engineer expects centralized config files in `.allhands/workflows/` — one per scoping domain (milestone, investigation, optimization, refactor, documentation, triage). Each file has:
|
|
29
|
+
|
|
30
|
+
- **Schema-validated frontmatter** for structured configuration (domain key, required inputs, applicable considerations, configuration flags)
|
|
31
|
+
- **Markdown body** for freetext domain knowledge (considerations, applications, use cases, interview dimensions, domain-specific guidance)
|
|
32
|
+
|
|
33
|
+
These files are the single source of truth for what makes each domain's workflow distinct. All three core flows consume them. The consuming flow decides abstraction level:
|
|
34
|
+
|
|
35
|
+
| Flow | How it uses domain config |
|
|
36
|
+
|------|---------------------------|
|
|
37
|
+
| Ideation Scoping | High-level interview dimensions, required ideation questions, grounding depth |
|
|
38
|
+
| Spec Planning | Constraint/limitation/edge-case considerations, approach evaluation criteria, planning depth calibration |
|
|
39
|
+
| Initiative Steering | Implementation-level question framing, current-state evaluation criteria, prompt adjustment guidance |
|
|
40
|
+
|
|
41
|
+
Engineer expects a schema for these files (via `ah schema workflow`) with validation on write, following the harness pattern of schema-driven file contracts (Pillar 7).
|
|
42
|
+
|
|
43
|
+
Engineer expects the existing milestone workflow behavior to be fully preserved by encoding it in a `milestone.md` workflow domain config file. The milestone config should capture all domain-specific knowledge that currently lives in `IDEATION_SESSION.md` and the milestone path of `SPEC_PLANNING.md`. Specifically:
|
|
44
|
+
|
|
45
|
+
**Milestone ideation knowledge (currently in IDEATION_SESSION.md):**
|
|
46
|
+
- 6 core interview dimensions: goals, motivations, concerns, desires, capabilities, expectations
|
|
47
|
+
- Category deep dives: UX (user journeys), data/state (storage, schema), technical (system constraints), scale (capacity), integrations (external services), security (access, sensitive data)
|
|
48
|
+
- Knowledge gap detection patterns and probing signals ("I think...", "just simple X", technology buzzwords without context, conflicting requirements)
|
|
49
|
+
- Completeness check criteria (problem statement clear, technical constraints understood, user expectations deeply understood, all elements have expectation or open question, no TBD items)
|
|
50
|
+
- Feasibility feedback presentation grounded in exploration results
|
|
51
|
+
- Guiding principles synthesis from engineer's philosophy (validated with engineer)
|
|
52
|
+
- Continuous research spawning as new concepts emerge during interview
|
|
53
|
+
|
|
54
|
+
**Milestone planning knowledge (currently in SPEC_PLANNING.md milestone path):**
|
|
55
|
+
- Deep research: 1-4 codebase understanding subtasks, 0-3 external research subtasks
|
|
56
|
+
- Full engineer interview with decision points: 2-4 options per question, recommended approach marked, adapt subsequent questions based on prior answers
|
|
57
|
+
- Disposable variant architecture: multi-select triggers parallel variant prompts behind feature flags, engineer must choose a convention when selecting multiple approaches
|
|
58
|
+
- External tech documentation research (EXTERNAL_TECH_GUIDANCE.md subtasks) for consolidating approaches against actual documentation
|
|
59
|
+
- Validation suite discovery and assignment via UTILIZE_VALIDATION_TOOLING.md
|
|
60
|
+
- TDD workflow flagging for high-risk domains (auth, payments, data)
|
|
61
|
+
- Plan verification self-check before jury: requirement coverage, task completeness, key links, scope sanity (2-3 tasks per prompt, <7 files), validation coverage
|
|
62
|
+
- 4-member jury review: expectations fit, flow analysis, YAGNI, premortem (Tigers = P1/P2, Elephants = discussion points)
|
|
63
|
+
- Review options breakdown after jury with actionable options for engineer
|
|
64
|
+
- Plan deepening option for complex/high-risk specs
|
|
65
|
+
- Alignment doc decision recording: only deviations from recommendations (what was recommended, what was chosen, stated reasoning)
|
|
66
|
+
- Solutions search and memories search during context gathering
|
|
67
|
+
- Prompt output range: 5-15 coordinated prompts for milestone, 0-3 seed prompts for exploratory
|
|
68
|
+
|
|
69
|
+
The milestone workflow domain config encodes the domain-specific knowledge (what to explore, what to consider, what to check). The unified flows preserve the orchestration logic (how to interview, how to spawn subtasks, how to sequence phases). The abstraction must not lose any of these practices — they are the result of iterative refinement and represent proven milestone development patterns.
|
|
70
|
+
|
|
71
|
+
### 2. Unified Ideation Scoping Flow
|
|
72
|
+
|
|
73
|
+
Engineer expects ONE generic `IDEATION_SCOPING.md` flow replacing all separate domain-specific scoping flows. This flow:
|
|
74
|
+
|
|
75
|
+
- Receives the workflow domain config file path as a template variable (`WORKFLOW_DOMAIN_PATH`)
|
|
76
|
+
- Adapts its interview behavior based on the domain config (required questions, consideration dimensions, grounding depth)
|
|
77
|
+
- Asks any required ideation questions specified in the domain config to ensure coverage of irreducible dimensions per domain
|
|
78
|
+
- Maintains **Ideation First** adherence: engineers control depth — they can leave open questions, go as detailed or light as they choose. The domain config ensures coverage without forcing depth
|
|
79
|
+
- Grounds using knowledge search across ROADMAP then DOCS indexes (in that order), plus required external research. Follows existing grounding patterns for codebase reality validation
|
|
80
|
+
- Presents feasibility feedback to the engineer grounded in exploration results (as the milestone flow does today)
|
|
81
|
+
- Spawns additional research subtasks as new concepts emerge during the interview to keep ideas fresh and grounded
|
|
82
|
+
- Synthesizes guiding principles from the engineer's philosophy and validates them (for domains where this applies)
|
|
83
|
+
- Produces spec files with assumptions about other roadmap specs (cross-domain), enabling ideation phases to build on top of each other without implementation
|
|
84
|
+
- Writes the `initial_workflow_domain` field to the spec's frontmatter
|
|
85
|
+
- Delegates to `CREATE_SPEC.md` for persistence (unchanged)
|
|
86
|
+
|
|
87
|
+
The flow is domain-agnostic orchestration. The domain config provides domain-specific substance. For milestone domains, the flow behavior should be functionally equivalent to the current `IDEATION_SESSION.md` — the abstraction changes where domain knowledge lives, not what happens during the session.
|
|
88
|
+
|
|
89
|
+
### 3. Spec Schema Update
|
|
90
|
+
|
|
91
|
+
Engineer expects a new `initial_workflow_domain` frontmatter field on the spec schema:
|
|
92
|
+
|
|
93
|
+
- Records which workflow domain config was used during ideation
|
|
94
|
+
- Enables downstream flows (spec planning, initiative steering) to automatically load the correct domain config
|
|
95
|
+
- Missing field treated as `milestone` for backward compatibility with existing specs — no migration needed
|
|
96
|
+
|
|
97
|
+
### 4. Spec Planning Domain Awareness
|
|
98
|
+
|
|
99
|
+
Engineer expects the spec planning flow (`SPEC_PLANNING.md`) to receive and consume the workflow domain config alongside the spec file. The domain config drives:
|
|
100
|
+
|
|
101
|
+
- What constraints, limitations, and edge cases to surface during deep grounding
|
|
102
|
+
- What considerations to evaluate approaches against
|
|
103
|
+
- Planning depth calibration (milestone: deep research + jury review; exploratory domains: focused research, no jury)
|
|
104
|
+
|
|
105
|
+
The spec planning agent's core role is unchanged: deep codebase and research grounding to reveal what ideation could not see, challenging approaches with grounded recommendations, clarifying open questions with options. The domain config adds structured awareness of domain-specific concerns to this process. The distinction from ideation scoping is that spec planning is designed to catch unseen constraints, limitations, and edge cases after deep grounding and external tech research, and to ask for clarification on open questions while challenging approaches with implementation-level recommendations.
|
|
106
|
+
|
|
107
|
+
For milestone domains, the spec planning flow must preserve the full planning pipeline:
|
|
108
|
+
- Deep research subtask spawning (1-4 codebase, 0-3 external research)
|
|
109
|
+
- Full engineer interview with recommended approaches and multi-select support
|
|
110
|
+
- Disposable variant architecture when engineer selects multiple approaches (parallel variant prompts behind feature flags, convention selection)
|
|
111
|
+
- External tech documentation research via EXTERNAL_TECH_GUIDANCE.md
|
|
112
|
+
- Validation suite discovery and assignment via UTILIZE_VALIDATION_TOOLING.md
|
|
113
|
+
- TDD workflow flagging for high-risk domains
|
|
114
|
+
- Plan verification self-check before jury (requirement coverage, task completeness, key links, scope sanity, validation coverage)
|
|
115
|
+
- 4-member jury review (expectations fit, flow analysis, YAGNI, premortem) with review options breakdown
|
|
116
|
+
- Plan deepening option for complex/high-risk specs
|
|
117
|
+
- Solutions and memories search during context gathering
|
|
118
|
+
- Decision recording: only deviations from recommendations
|
|
119
|
+
|
|
120
|
+
The domain config determines which of these phases activate. Milestone activates all of them. Exploratory domains activate a subset (focused research, open question interview, seed prompt creation, no jury, no variants).
|
|
121
|
+
|
|
122
|
+
**Execution gating**: Engineer expects spec planning to be the explicit gate for execution. The planner sets `stage: executing` on `status.yaml`, which is the signal that the loop can start picking up prompts and emergence can begin. No prompts execute before the planner transitions this status, even if prompts already exist from a previous planning attempt.
|
|
123
|
+
|
|
124
|
+
**Idempotency**: Engineer desires spec planning to support rerunning. When existing planning artifacts are detected, the planner offers two modes:
|
|
125
|
+
- **Start fresh** — Clears `.planning/` artifacts (prompts, alignment doc) and replans from the spec
|
|
126
|
+
- **Amend** — Reads existing alignment doc and prompts, produces amendments without re-litigating existing decisions
|
|
127
|
+
|
|
128
|
+
### 5. Initiative Steering Flow
|
|
129
|
+
|
|
130
|
+
Engineer expects a new `INITIATIVE_STEERING.md` flow for mid-execution scope adjustment. This is the third core flow alongside ideation scoping and spec planning.
|
|
131
|
+
|
|
132
|
+
Key characteristics:
|
|
133
|
+
|
|
134
|
+
- **Input is user's direct input** — no intermediate spec file. The user speaks at implementation level because they have context from the running work
|
|
135
|
+
- Receives the active spec, alignment doc, prompts folder, implementation diffs, and workflow domain config
|
|
136
|
+
- The workflow domain config can be the same domain as the active spec OR a different domain (e.g., milestone spec encounters a bug, engineer steers with investigation domain config)
|
|
137
|
+
- Does deep grounding similar to spec planning, but uses current implementation diffs and existing/future prompt files as additional heuristics for current state of the world — this is a core difference from spec planning which grounds against the spec alone
|
|
138
|
+
- Asks domain-specific questions driven by the workflow domain config, framed at implementation level against current execution state
|
|
139
|
+
- Produces: alignment doc goal/initiative summary updates, prompt insertions/modifications/deletions with dependency consistency (following the coordinator's append-only numbering and dependency patching patterns), records all decisions and user inputs in the alignment doc
|
|
140
|
+
- Does NOT add prompt summaries for created prompts — that remains the executing agent's responsibility
|
|
141
|
+
- Resets `core_consolidation` to `pending` on the alignment doc when initiative goals change
|
|
142
|
+
|
|
143
|
+
Engineer desires initiative steering to be distinct from the coordinator. The coordinator remains a versatile, quick-action agent for miscellaneous fixes (quick patches, emergent prompt triage, prompt surgery, agent management). Initiative steering is a structured, domain-aware deep replanning session.
|
|
144
|
+
|
|
145
|
+
### 6. Two-Phase Emergence Model
|
|
146
|
+
|
|
147
|
+
Engineer expects emergence to operate in two explicit phases:
|
|
148
|
+
|
|
149
|
+
**Phase 1 — Core Consolidation**: Emergent hypotheses that verify, solidify, and compound the implementation to convincingly meet the core initiative goals. The emergent planner focuses on gaps between current implementation state and the alignment doc's stated goals and expectations.
|
|
150
|
+
|
|
151
|
+
**Phase 2 — Tangential Exploration**: Only after core goals are convincingly met. Emergent hypotheses that extend the implementation with ideas adjacent to but not explicitly requested in the initial goals — feature ideas, consolidation, future-proofing, edge case coverage. These often result in feature-flagged additions. Capped at a configurable maximum hypothesis count to prevent unbounded scope expansion.
|
|
152
|
+
|
|
153
|
+
**State tracking**: A `core_consolidation: pending | complete` field on the alignment doc frontmatter. The emergent planner reads this to determine which phase it is in:
|
|
154
|
+
- When `pending`: hypotheses focus on core goal consolidation and verification
|
|
155
|
+
- When `complete`: hypotheses shift to tangential exploration within the configured cap
|
|
156
|
+
|
|
157
|
+
**Transition**: The emergent planner determines when core consolidation is complete — when it assesses that all core goals are convincingly met based on the alignment doc's goals, prompt summaries, and implementation state. It sets `core_consolidation: complete`.
|
|
158
|
+
|
|
159
|
+
**Initiative steering reset**: When initiative steering modifies goals, it resets `core_consolidation` to `pending`, requiring the emergent planner to re-verify against updated goals before entering tangential exploration.
|
|
160
|
+
|
|
161
|
+
**Prompt type**: Do not split `emergent` into `emergent_core` and `emergent_tangential`. The distinction is about the phase of emergence, not the type of prompt. Both are emergent hypotheses executed identically by executors. The compounding agent can determine phase from timestamps relative to when `core_consolidation` transitioned, if analysis is needed.
|
|
162
|
+
|
|
163
|
+
### 7. Alignment Doc Schema Update
|
|
164
|
+
|
|
165
|
+
Engineer expects the alignment doc schema to include:
|
|
166
|
+
- `core_consolidation: pending | complete` in frontmatter (default: `pending`)
|
|
167
|
+
- Set to `complete` by emergent agents when core goals are convincingly met
|
|
168
|
+
- Reset to `pending` by initiative steering when goals change
|
|
169
|
+
|
|
170
|
+
The alignment doc remains append-only for decisions and prompt summaries. Initiative steering appends its amendments (goal updates, new decisions, user inputs) rather than rewriting existing content, preserving the audit trail.
|
|
171
|
+
|
|
172
|
+
### 8. Workflow Config Delivery to Agents
|
|
173
|
+
|
|
174
|
+
Engineer expects workflow domain config to reach agents via template variables on agent profiles:
|
|
175
|
+
- The TUI's "New Initiative" action resolves the workflow domain, provides the path as `WORKFLOW_DOMAIN_PATH` template variable to the ideation scoping agent
|
|
176
|
+
- Spec planning and initiative steering agents resolve the workflow domain from the spec's `initial_workflow_domain` field, loading the corresponding config from `.allhands/workflows/`
|
|
177
|
+
|
|
178
|
+
### 9. Remove Separate Scoping Flows
|
|
179
|
+
|
|
180
|
+
Engineer expects the following flows to be retired once the unified ideation scoping flow and workflow domain configs are operational:
|
|
181
|
+
|
|
182
|
+
- `IDEATION_SESSION.md` (replaced by `IDEATION_SCOPING.md`)
|
|
183
|
+
- `INVESTIGATION_SCOPING.md`
|
|
184
|
+
- `OPTIMIZATION_SCOPING.md`
|
|
185
|
+
- `REFACTOR_SCOPING.md`
|
|
186
|
+
- `DOCUMENTATION_SCOPING.md`
|
|
187
|
+
- `TRIAGE_SCOPING.md`
|
|
188
|
+
|
|
189
|
+
Domain-specific knowledge from these flows migrates into the corresponding workflow domain config files in `.allhands/workflows/`.
|
|
190
|
+
|
|
191
|
+
### 10. Pillar Updates
|
|
192
|
+
|
|
193
|
+
Engineer expects minimal, non-invasive updates to `.allhands/pillars.md`:
|
|
194
|
+
- **Pillar 8 (Initiative-Based Orchestration)**: Update to reference workflow domain configs as the mechanism that drives scoping, planning, and steering behavior per initiative type. Add initiative steering as a first-class mid-execution intervention concept alongside the existing coordinator
|
|
195
|
+
- Other pillars should remain unchanged unless a natural fit emerges during implementation
|
|
196
|
+
|
|
197
|
+
## Non-Goals
|
|
198
|
+
|
|
199
|
+
- **Spec completion and switching workflows** — Git merge prep, file movement, push operations, and worktree-aware spec switching are separate concerns for a downstream spec
|
|
200
|
+
- **Changing the executor agent or prompt execution flow** — Executors are unchanged. They pick up prompts regardless of how those prompts were created (planned, emergent, steered)
|
|
201
|
+
- **Changing the coordinator agent's core role** — The coordinator remains a versatile quick-action agent. Initiative steering is a separate flow with a separate agent
|
|
202
|
+
- **Automated domain detection** — The user selects the workflow domain. No inference from branch name, spec content, or execution state
|
|
203
|
+
- **New scoping domains beyond the existing six** — This milestone establishes the workflow domain configuration model and migrates existing domains. Adding new domains is trivial once the model exists
|
|
204
|
+
- **CI/CD pipeline changes** — Schema validation for workflow configs is in scope; CI pipeline integration for new file types is downstream
|
|
205
|
+
|
|
206
|
+
## Open Questions
|
|
207
|
+
|
|
208
|
+
- **Workflow domain config schema depth** — How much structure should the frontmatter carry vs. the markdown body? The frontmatter needs at minimum: `name`, `type` (matching spec types), and required ideation questions. The markdown body provides freetext considerations and domain knowledge. Architect should determine the right balance between programmatic access (frontmatter) and expressive domain knowledge (markdown body)
|
|
209
|
+
- **Initiative steering invocation mechanism** — Should initiative steering be a dedicated TUI action (like the planner), invoked through the "New Initiative" modal with an "adjust current" option, or a new TUI action entirely? A dedicated TUI action is most discoverable. Architect should determine the right UX pattern
|
|
210
|
+
- **Initiative steering and the event loop** — Should the event loop pause while initiative steering is active, or can it continue executing existing prompts? Pausing is safer (avoids race conditions with prompt modifications) but slower. Architect should evaluate the tradeoff
|
|
211
|
+
- **Tangential hypothesis cap configuration** — Where should the maximum tangential emergence hypothesis count be configured? Options: alignment doc frontmatter, workflow domain config, settings.json global default, or spec frontmatter. Domain config is most natural (some domains may warrant more exploration than others)
|
|
212
|
+
- **Spec planning "amend" mode — staleness detection** — When amending existing planning artifacts, how does the planner distinguish "existing decisions to preserve" from "stale decisions to revisit"? The alignment doc's append-only log helps, but guidance on what constitutes "stale" is needed — perhaps decisions referencing prompts that no longer exist or have been significantly modified
|
|
213
|
+
- **Initiative steering workflow domain selection** — When steering with a different domain than the active spec (e.g., milestone spec needs investigation steering), should the spec's `initial_workflow_domain` be updated, or should the steering domain be tracked separately in the alignment doc? Updating the spec changes its identity; separate tracking adds state but preserves the original domain record
|
|
214
|
+
- **Milestone workflow config completeness** — The milestone domain is the most complex (6-dimension interview, completeness checks, jury review during planning, plan deepening). How much of the existing milestone flow logic should migrate into the domain config vs. remain as conditional paths in the unified flows? The domain config should describe WHAT to explore; the flow should handle HOW to orchestrate. The boundary between domain knowledge and flow logic needs careful placement
|
|
215
|
+
|
|
216
|
+
## Technical Considerations
|
|
217
|
+
|
|
218
|
+
- **Workflow domain config files are schema-validated** — Following Pillar 7, `ah schema workflow` defines the frontmatter structure. Validation runs on write. The `ah` CLI needs a new schema definition and corresponding validation
|
|
219
|
+
- **Template variable delivery** — Agent profiles already support template variables (`SPEC_NAME`, `SPEC_PATH`, `ALIGNMENT_PATH`, `PROMPTS_FOLDER`). Adding `WORKFLOW_DOMAIN_PATH` follows the existing pattern. The TUI resolves the path from the selected workflow domain and passes it to the agent profile's template expansion
|
|
220
|
+
- **Spec frontmatter backward compatibility** — Existing specs lack `initial_workflow_domain`. Treat missing field as `milestone`. No migration needed
|
|
221
|
+
- **Unified scoping flow depth range** — The single `IDEATION_SCOPING.md` must handle milestone's deep 6-dimension interview with parallel grounding and completeness checks down to investigation's 5 focused questions. Per **Frontier Models are Capable**, the flow provides orchestration scaffolding while the domain config provides domain-specific substance. The model deduces appropriate depth from the domain config's content
|
|
222
|
+
- **Initiative steering prompt dependency management** — When inserting, modifying, or deleting prompts mid-execution, dependency consistency must be maintained. The coordinator flow already has a proven pattern for this: append-only numbering, explicit dependency patching on affected prompts. Initiative steering follows the same pattern. `pickNextPrompt()` already handles dependency resolution generically
|
|
223
|
+
- **Alignment doc amendment pattern** — Initiative steering appends to the alignment doc. A new section (e.g., `## Steering Amendments`) or appending to existing sections preserves the append-only audit trail while clearly marking what changed. Each amendment records: the steering domain used, user inputs, decisions made, and prompt changes
|
|
224
|
+
- **Emergence phase transition is a flow change** — The emergent planner already reads the alignment doc. Adding `core_consolidation` awareness is a flow change (checking the field, adjusting hypothesis strategy), not a code change to the harness runtime
|
|
225
|
+
- **Event loop gating invariant** — The `stage` field on `status.yaml` already gates execution. Making spec planning the explicit setter of `stage: executing` enforces an invariant rather than adding a new mechanism. The loop's `checkPromptLoop()` already checks status before spawning
|
|
226
|
+
- **Existing milestone behavior preservation** — The milestone workflow domain config encodes the domain knowledge; the unified flows preserve the orchestration logic. The milestone planning path (deep research subtasks, full engineer interview with options, external tech research, jury review, plan deepening) remains as conditional flow logic triggered by the milestone domain config's characteristics
|
|
227
|
+
|
|
228
|
+
## Implementation Reality
|
|
229
|
+
|
|
230
|
+
### What Was Implemented vs Planned
|
|
231
|
+
|
|
232
|
+
All 10 spec goals were implemented as planned across 13 prompts (10 planned + 3 review-fix from jury review). No goals were descoped, deferred, or significantly altered. The engineer declined YAGNI scope reduction, keeping full scope: all 6 domain configs, amend mode, and two-phase emergence.
|
|
233
|
+
|
|
234
|
+
### Key Technical Decisions
|
|
235
|
+
|
|
236
|
+
- **Content-presence branching over type checks**: The unified `IDEATION_SCOPING.md` triggers milestone-specific features (deep dives, gap detection, completeness check, guiding principles) by detecting content presence in domain config sections rather than hardcoded `planning_depth` or `type` checks. This enables new domains to activate features by adding config content without flow code changes.
|
|
237
|
+
- **"Deep Planning" / "Focused Planning" naming**: Planning paths were named to decouple from spec type terminology. `planning_depth: deep` activates the full pipeline; `planning_depth: focused` activates the lightweight path.
|
|
238
|
+
- **Stage-field loop pause over window detection**: Initiative steering pauses the event loop via `stage: 'steering'` on `status.yaml` rather than window-name-based detection — uses the same mechanism as execution gating for architectural consistency.
|
|
239
|
+
- **`status: deleted` for prompt deletion**: Initiative steering marks prompts as deleted in frontmatter rather than removing files, preserving the audit trail.
|
|
240
|
+
- **`contextOverrides` for domain selection**: TUI actions pass engineer's domain selection to agents via `contextOverrides` on `spawnAgentsForAction()` rather than mutating global template context.
|
|
241
|
+
|
|
242
|
+
### Jury Review Outcomes
|
|
243
|
+
|
|
244
|
+
The 7-member post-implementation jury caught 5 P1/P2 issues resolved by review-fix prompts 11-13:
|
|
245
|
+
- Duplicated regex frontmatter parsing → extracted shared `getWorkflowDomain()` utility with proper YAML parsing
|
|
246
|
+
- Unsanitized domain values in `path.join()` → added `VALID_WORKFLOW_DOMAINS` allowlist validation
|
|
247
|
+
- Missing `initial_workflow_domain` on `SpecFrontmatter` interface → added to type definition
|
|
248
|
+
- Missing `ALIGNMENT_PATH` on planner agent profile → added to template vars
|
|
249
|
+
- Tautological routing tests asserting constants against themselves → replaced with filesystem/runtime assertions
|
|
250
|
+
- Duplicated 6-domain array in TUI modals → extracted shared `WORKFLOW_DOMAIN_ITEMS` constant
|
|
251
|
+
- 5 workflow domain patterns not encoded in harness-maintenance skill → encoded as new skill sections
|
|
252
|
+
|
|
253
|
+
### Open Questions Resolved
|
|
254
|
+
|
|
255
|
+
- **Schema depth**: Structured frontmatter for programmatic flags (`planning_depth`, `jury_required`, `max_tangential_hypotheses`, `required_ideation_questions`) + markdown body for expressive domain knowledge
|
|
256
|
+
- **Initiative steering invocation**: Dedicated TUI action ("Steer Initiative") with domain selection modal
|
|
257
|
+
- **Event loop during steering**: Paused via `stage: 'steering'` — active executors continue, no new spawns
|
|
258
|
+
- **Tangential hypothesis cap**: Configured per domain in workflow domain config's `max_tangential_hypotheses` field
|
|
259
|
+
- **Amend mode staleness**: Reference integrity check — decisions referencing prompts that no longer exist or with modified acceptance criteria are flagged as stale
|
|
260
|
+
- **Steering domain tracking**: Tracked in alignment doc amendment section, not by updating `initial_workflow_domain` on the spec
|
|
261
|
+
- **Milestone config completeness**: Domain config describes WHAT (6-dimension interview, gap signals, completeness criteria, jury topics); unified flows handle HOW (subtask spawning, interview sequencing, phase orchestration). `planning_depth` and `jury_required` flags gate which flow phases activate.
|
|
262
|
+
|
|
263
|
+
### Validation Gap
|
|
264
|
+
|
|
265
|
+
No TypeScript-specific validation suite exists. All 13 prompts used `validation_suites: []`. Manual validation relied on `tsc --noEmit`, `npx vitest run`, `ah validate agents/file`, and manual acceptance criteria walkthroughs. This gap was previously identified and persists.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { existsSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { isGitRepo } from '../lib/git.js';
|
|
4
|
+
import { SYNC_CONFIG_FILENAME, SYNC_CONFIG_TEMPLATE } from '../lib/constants.js';
|
|
5
|
+
|
|
6
|
+
export async function cmdPullManifest(): Promise<number> {
|
|
7
|
+
const cwd = process.cwd();
|
|
8
|
+
|
|
9
|
+
if (!isGitRepo(cwd)) {
|
|
10
|
+
console.error('Error: Not in a git repository');
|
|
11
|
+
return 1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const configPath = join(cwd, SYNC_CONFIG_FILENAME);
|
|
15
|
+
|
|
16
|
+
if (existsSync(configPath)) {
|
|
17
|
+
console.error(`Error: ${SYNC_CONFIG_FILENAME} already exists`);
|
|
18
|
+
console.error('Remove it first if you want to regenerate');
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
writeFileSync(configPath, JSON.stringify(SYNC_CONFIG_TEMPLATE, null, 2) + '\n');
|
|
23
|
+
|
|
24
|
+
console.log(`Created ${SYNC_CONFIG_FILENAME}`);
|
|
25
|
+
console.log('\nUsage:');
|
|
26
|
+
console.log(' - Add file paths to "includes" to push additional files');
|
|
27
|
+
console.log(' - Add file paths to "excludes" to skip tracking changes');
|
|
28
|
+
console.log(' - Commit this file to persist your push configuration');
|
|
29
|
+
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, rmSync } from 'fs';
|
|
2
|
+
import { tmpdir } from 'os';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { minimatch } from 'minimatch';
|
|
5
|
+
import * as readline from 'readline';
|
|
6
|
+
import { git, isGitRepo, getGitFiles } from '../lib/git.js';
|
|
7
|
+
import { checkGhAuth, checkGhInstalled, getGhUser, gh } from '../lib/gh.js';
|
|
8
|
+
import { Manifest, filesAreDifferent } from '../lib/manifest.js';
|
|
9
|
+
import { getAllhandsRoot, UPSTREAM_REPO } from '../lib/paths.js';
|
|
10
|
+
import { askQuestion, confirm } from '../lib/ui.js';
|
|
11
|
+
import { PUSH_BLOCKLIST, SYNC_CONFIG_FILENAME } from '../lib/constants.js';
|
|
12
|
+
|
|
13
|
+
interface SyncConfig {
|
|
14
|
+
includes?: string[];
|
|
15
|
+
excludes?: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface FileEntry {
|
|
19
|
+
path: string;
|
|
20
|
+
type: 'M' | 'A';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface PrerequisiteResult {
|
|
24
|
+
success: boolean;
|
|
25
|
+
ghUser?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function loadSyncConfig(cwd: string): SyncConfig | null {
|
|
29
|
+
const configPath = join(cwd, SYNC_CONFIG_FILENAME);
|
|
30
|
+
if (!existsSync(configPath)) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const content = readFileSync(configPath, 'utf-8');
|
|
35
|
+
return JSON.parse(content);
|
|
36
|
+
} catch (e) {
|
|
37
|
+
throw new Error(`Failed to parse ${SYNC_CONFIG_FILENAME}: ${e instanceof Error ? e.message : String(e)}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function expandGlob(pattern: string, baseDir: string): string[] {
|
|
42
|
+
const allFiles = getGitFiles(baseDir);
|
|
43
|
+
return allFiles.filter((relPath) => minimatch(relPath, pattern, { dot: true }));
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function askMultiLineInput(prompt: string): Promise<string> {
|
|
47
|
+
console.log(prompt);
|
|
48
|
+
console.log('(Enter an empty line to finish)');
|
|
49
|
+
|
|
50
|
+
const lines: string[] = [];
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
const askLine = () => {
|
|
58
|
+
rl.question('', (line: string) => {
|
|
59
|
+
if (line === '') {
|
|
60
|
+
rl.close();
|
|
61
|
+
resolve(lines.join('\n'));
|
|
62
|
+
} else {
|
|
63
|
+
lines.push(line);
|
|
64
|
+
askLine();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
askLine();
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function checkPrerequisites(cwd: string): PrerequisiteResult {
|
|
73
|
+
if (!checkGhInstalled()) {
|
|
74
|
+
console.error('Error: gh CLI required. Install: https://cli.github.com');
|
|
75
|
+
return { success: false };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!checkGhAuth()) {
|
|
79
|
+
console.error('Error: Not authenticated. Run: gh auth login');
|
|
80
|
+
return { success: false };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!isGitRepo(cwd)) {
|
|
84
|
+
console.error('Error: Not in a git repository');
|
|
85
|
+
return { success: false };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const ghUser = getGhUser();
|
|
89
|
+
if (!ghUser) {
|
|
90
|
+
console.error('Error: Could not determine GitHub username');
|
|
91
|
+
return { success: false };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return { success: true, ghUser };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function collectFilesToPush(
|
|
98
|
+
cwd: string,
|
|
99
|
+
finalIncludes: string[],
|
|
100
|
+
finalExcludes: string[]
|
|
101
|
+
): FileEntry[] {
|
|
102
|
+
const allhandsRoot = getAllhandsRoot();
|
|
103
|
+
const manifest = new Manifest(allhandsRoot);
|
|
104
|
+
const upstreamFiles = manifest.getDistributableFiles();
|
|
105
|
+
const filesToPush: FileEntry[] = [];
|
|
106
|
+
|
|
107
|
+
// Get non-ignored files in user's repo (respects .gitignore)
|
|
108
|
+
const localGitFiles = new Set(getGitFiles(cwd));
|
|
109
|
+
|
|
110
|
+
for (const relPath of upstreamFiles) {
|
|
111
|
+
if (manifest.isInitOnly(relPath)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (PUSH_BLOCKLIST.includes(relPath)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
if (finalExcludes.some((pattern) => minimatch(relPath, pattern, { dot: true }))) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Skip files that are gitignored in user's repo
|
|
121
|
+
if (!localGitFiles.has(relPath)) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const localFile = join(cwd, relPath);
|
|
126
|
+
const upstreamFile = join(allhandsRoot, relPath);
|
|
127
|
+
|
|
128
|
+
if (existsSync(localFile) && filesAreDifferent(localFile, upstreamFile)) {
|
|
129
|
+
filesToPush.push({ path: relPath, type: 'M' });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
for (const pattern of finalIncludes) {
|
|
134
|
+
const matchedFiles = expandGlob(pattern, cwd);
|
|
135
|
+
for (const relPath of matchedFiles) {
|
|
136
|
+
if (manifest.isInitOnly(relPath)) continue;
|
|
137
|
+
if (PUSH_BLOCKLIST.includes(relPath)) continue;
|
|
138
|
+
if (finalExcludes.some((p) => minimatch(relPath, p, { dot: true }))) continue;
|
|
139
|
+
if (filesToPush.some((f) => f.path === relPath)) continue;
|
|
140
|
+
|
|
141
|
+
const localFile = join(cwd, relPath);
|
|
142
|
+
const upstreamFile = join(allhandsRoot, relPath);
|
|
143
|
+
|
|
144
|
+
// Skip files that exist in upstream and are identical
|
|
145
|
+
if (existsSync(upstreamFile) && !filesAreDifferent(localFile, upstreamFile)) {
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
filesToPush.push({ path: relPath, type: 'A' });
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return filesToPush;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function waitForFork(ghUser: string, repoName: string): Promise<boolean> {
|
|
157
|
+
console.log('Waiting for fork to be ready...');
|
|
158
|
+
for (let i = 0; i < 15; i++) {
|
|
159
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
160
|
+
if (gh(['repo', 'view', `${ghUser}/${repoName}`, '--json', 'name']).success) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function createPullRequest(
|
|
168
|
+
cwd: string,
|
|
169
|
+
ghUser: string,
|
|
170
|
+
filesToPush: FileEntry[],
|
|
171
|
+
title: string,
|
|
172
|
+
body: string
|
|
173
|
+
): Promise<number> {
|
|
174
|
+
const repoName = UPSTREAM_REPO.split('/')[1];
|
|
175
|
+
const forkCheck = gh(['repo', 'view', `${ghUser}/${repoName}`, '--json', 'name']);
|
|
176
|
+
|
|
177
|
+
if (!forkCheck.success) {
|
|
178
|
+
console.log('Creating fork...');
|
|
179
|
+
const forkResult = gh(['repo', 'fork', UPSTREAM_REPO, '--clone=false']);
|
|
180
|
+
if (!forkResult.success) {
|
|
181
|
+
console.error('Error creating fork:', forkResult.stderr);
|
|
182
|
+
return 1;
|
|
183
|
+
}
|
|
184
|
+
if (!(await waitForFork(ghUser, repoName))) {
|
|
185
|
+
console.error('Error: Timed out waiting for fork to be ready.');
|
|
186
|
+
return 1;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const tempDir = join(tmpdir(), `allhands-push-${Date.now()}`);
|
|
191
|
+
mkdirSync(tempDir, { recursive: true });
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
console.log('Cloning fork...');
|
|
195
|
+
const cloneResult = gh(['repo', 'clone', `${ghUser}/${repoName}`, tempDir, '--', '--depth=1']);
|
|
196
|
+
if (!cloneResult.success) {
|
|
197
|
+
console.error('Error cloning fork:', cloneResult.stderr);
|
|
198
|
+
return 1;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
console.log('Fetching upstream...');
|
|
202
|
+
const addRemoteResult = git(['remote', 'add', 'upstream', `https://github.com/${UPSTREAM_REPO}`], tempDir);
|
|
203
|
+
if (!addRemoteResult.success) {
|
|
204
|
+
console.error('Error adding upstream remote:', addRemoteResult.stderr);
|
|
205
|
+
return 1;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const fetchResult = git(['fetch', 'upstream', 'main', '--depth=1'], tempDir);
|
|
209
|
+
if (!fetchResult.success) {
|
|
210
|
+
console.error('Error fetching upstream:', fetchResult.stderr);
|
|
211
|
+
return 1;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const branchName = `contrib/${ghUser}/${Date.now()}`;
|
|
215
|
+
console.log(`Creating branch: ${branchName}`);
|
|
216
|
+
|
|
217
|
+
const checkoutResult = git(['checkout', '-b', branchName, 'upstream/main'], tempDir);
|
|
218
|
+
if (!checkoutResult.success) {
|
|
219
|
+
console.error('Error creating branch:', checkoutResult.stderr);
|
|
220
|
+
return 1;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
console.log('Copying files...');
|
|
224
|
+
for (const file of filesToPush) {
|
|
225
|
+
const src = join(cwd, file.path);
|
|
226
|
+
const dest = join(tempDir, file.path);
|
|
227
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
228
|
+
copyFileSync(src, dest);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const addResult = git(['add', '.'], tempDir);
|
|
232
|
+
if (!addResult.success) {
|
|
233
|
+
console.error('Error staging files:', addResult.stderr);
|
|
234
|
+
return 1;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const commitResult = git(['commit', '-m', title], tempDir);
|
|
238
|
+
if (!commitResult.success) {
|
|
239
|
+
console.error('Error committing:', commitResult.stderr);
|
|
240
|
+
return 1;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
console.log('Pushing to fork...');
|
|
244
|
+
const pushResult = git(['push', '-u', 'origin', branchName], tempDir);
|
|
245
|
+
if (!pushResult.success) {
|
|
246
|
+
console.error('Error pushing:', pushResult.stderr);
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
console.log('Creating PR...');
|
|
251
|
+
const prArgs = [
|
|
252
|
+
'pr', 'create',
|
|
253
|
+
'--repo', UPSTREAM_REPO,
|
|
254
|
+
'--head', `${ghUser}:${branchName}`,
|
|
255
|
+
'--title', title,
|
|
256
|
+
'--body', body || 'Contribution via claude-all-hands push',
|
|
257
|
+
];
|
|
258
|
+
|
|
259
|
+
const prResult = gh(prArgs);
|
|
260
|
+
if (!prResult.success) {
|
|
261
|
+
console.error('Error creating PR:', prResult.stderr);
|
|
262
|
+
return 1;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
console.log('\nPR created successfully!');
|
|
266
|
+
console.log(prResult.stdout);
|
|
267
|
+
|
|
268
|
+
return 0;
|
|
269
|
+
} finally {
|
|
270
|
+
try {
|
|
271
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
272
|
+
} catch {
|
|
273
|
+
// Ignore cleanup errors
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export async function cmdPush(
|
|
279
|
+
include: string[],
|
|
280
|
+
exclude: string[],
|
|
281
|
+
dryRun: boolean,
|
|
282
|
+
titleArg?: string,
|
|
283
|
+
bodyArg?: string
|
|
284
|
+
): Promise<number> {
|
|
285
|
+
const cwd = process.cwd();
|
|
286
|
+
|
|
287
|
+
const prereqs = checkPrerequisites(cwd);
|
|
288
|
+
if (!prereqs.success) {
|
|
289
|
+
return 1;
|
|
290
|
+
}
|
|
291
|
+
const ghUser = prereqs.ghUser!;
|
|
292
|
+
|
|
293
|
+
let syncConfig: SyncConfig | null = null;
|
|
294
|
+
try {
|
|
295
|
+
syncConfig = loadSyncConfig(cwd);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
console.error(`Error: ${e instanceof Error ? e.message : String(e)}`);
|
|
298
|
+
return 1;
|
|
299
|
+
}
|
|
300
|
+
const finalIncludes = include.length > 0 ? include : (syncConfig?.includes || []);
|
|
301
|
+
const finalExcludes = exclude.length > 0 ? exclude : (syncConfig?.excludes || []);
|
|
302
|
+
|
|
303
|
+
const filesToPush = collectFilesToPush(cwd, finalIncludes, finalExcludes);
|
|
304
|
+
|
|
305
|
+
if (filesToPush.length === 0) {
|
|
306
|
+
console.log('No changes to push');
|
|
307
|
+
return 0;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
console.log('\nFiles to be included in PR:');
|
|
311
|
+
for (const file of filesToPush.sort((a, b) => a.path.localeCompare(b.path))) {
|
|
312
|
+
const marker = file.type === 'M' ? 'M' : 'A';
|
|
313
|
+
const label = file.type === 'M' ? 'modified' : 'included';
|
|
314
|
+
console.log(` ${marker} ${file.path} (${label})`);
|
|
315
|
+
}
|
|
316
|
+
console.log();
|
|
317
|
+
|
|
318
|
+
if (dryRun) {
|
|
319
|
+
console.log('Dry run - no PR created');
|
|
320
|
+
return 0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const title = titleArg || await askQuestion('PR title: ');
|
|
324
|
+
if (!title.trim()) {
|
|
325
|
+
console.error('Error: Title cannot be empty');
|
|
326
|
+
return 1;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const body = bodyArg !== undefined ? bodyArg : await askMultiLineInput('\nPR body:');
|
|
330
|
+
|
|
331
|
+
if (!titleArg) {
|
|
332
|
+
console.log();
|
|
333
|
+
if (!(await confirm(`Create PR with title "${title}"?`))) {
|
|
334
|
+
console.log('Aborted');
|
|
335
|
+
return 0;
|
|
336
|
+
}
|
|
337
|
+
} else {
|
|
338
|
+
console.log(`\nCreating PR: "${title}"`);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
console.log(`\nUsing GitHub account: ${ghUser}`);
|
|
342
|
+
|
|
343
|
+
return createPullRequest(cwd, ghUser, filesToPush, title, body);
|
|
344
|
+
}
|