atlas-workflow 0.9.2 → 0.9.4

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.
Files changed (113) hide show
  1. package/README.md +18 -9
  2. package/VERSION +1 -1
  3. package/build/bump-version.mjs +6 -21
  4. package/build/cli/atlas-init.mjs +92 -5
  5. package/build/tests/etapa3.test.mjs +36 -6
  6. package/hosts/opencode/.opencode/atlas/VERSION +1 -1
  7. package/hosts/opencode/.opencode/atlas/orchestrator/README.md +15 -2
  8. package/hosts/opencode/.opencode/atlas/orchestrator/commands/workflow.md +7 -5
  9. package/hosts/opencode/.opencode/atlas/orchestrator/references/host-adapters.md +13 -12
  10. package/hosts/opencode/.opencode/atlas/orchestrator/references/subagent_dispatch.md +11 -1
  11. package/hosts/opencode/.opencode/atlas/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
  12. package/hosts/opencode/.opencode/atlas/packages/mcp-server/README.md +2 -2
  13. package/hosts/opencode/.opencode/atlas/packages/mcp-server/package.json +1 -1
  14. package/hosts/opencode/.opencode/atlas/packages/mcp-server/server.js +149 -21
  15. package/hosts/opencode/.opencode/skills/_shared/references/stack-profiles.md +36 -0
  16. package/hosts/opencode/.opencode/skills/_shared/scripts/document_quality.mjs +37 -1
  17. package/hosts/opencode/.opencode/skills/atlas-audit/SKILL.md +201 -0
  18. package/hosts/opencode/.opencode/skills/atlas-audit/agents/openai.yaml +7 -0
  19. package/hosts/opencode/.opencode/skills/atlas-task-validator/SKILL.md +6 -0
  20. package/hosts/opencode/.opencode/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
  21. package/hosts/pi/atlas/VERSION +1 -1
  22. package/hosts/pi/atlas/orchestrator/README.md +15 -2
  23. package/hosts/pi/atlas/orchestrator/commands/workflow.md +7 -5
  24. package/hosts/pi/atlas/orchestrator/references/host-adapters.md +13 -12
  25. package/hosts/pi/atlas/orchestrator/references/subagent_dispatch.md +11 -1
  26. package/hosts/pi/atlas/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
  27. package/hosts/pi/atlas/packages/mcp-server/README.md +2 -2
  28. package/hosts/pi/atlas/packages/mcp-server/package.json +1 -1
  29. package/hosts/pi/atlas/packages/mcp-server/server.js +149 -21
  30. package/hosts/pi/skills/_shared/references/stack-profiles.md +36 -0
  31. package/hosts/pi/skills/_shared/scripts/document_quality.mjs +37 -1
  32. package/hosts/pi/skills/atlas-audit/SKILL.md +201 -0
  33. package/hosts/pi/skills/atlas-audit/agents/openai.yaml +7 -0
  34. package/hosts/pi/skills/atlas-task-validator/SKILL.md +6 -0
  35. package/hosts/pi/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
  36. package/hosts/zcode/.zcode-plugin/plugin.json +27 -0
  37. package/hosts/zcode/agents/atlas-direct-execute.md +31 -0
  38. package/hosts/zcode/agents/atlas-findings-repair.md +39 -0
  39. package/hosts/zcode/agents/atlas-plan-execute.md +33 -0
  40. package/hosts/zcode/agents/atlas-slice-review.md +27 -0
  41. package/hosts/zcode/agents/atlas-task-validator.md +138 -0
  42. package/hosts/zcode/packages/mcp-server/README.md +29 -0
  43. package/hosts/zcode/packages/mcp-server/VERSION +1 -0
  44. package/hosts/zcode/packages/mcp-server/package.json +15 -0
  45. package/hosts/zcode/packages/mcp-server/server.js +3963 -0
  46. package/hosts/zcode/packages/orchestrator/README.md +283 -0
  47. package/hosts/zcode/packages/orchestrator/commands/workflow.md +39 -0
  48. package/hosts/zcode/packages/orchestrator/defaults/paths.md +21 -0
  49. package/hosts/zcode/packages/orchestrator/references/host-adapters.md +106 -0
  50. package/hosts/zcode/packages/orchestrator/references/qa_s13_matrix.md +141 -0
  51. package/hosts/zcode/packages/orchestrator/references/subagent_dispatch.md +52 -0
  52. package/hosts/zcode/packages/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +411 -0
  53. package/hosts/zcode/packages/templates/BACKLOG_MESTRE_TEMPLATE.md +855 -0
  54. package/hosts/zcode/packages/templates/BOUNDARY_PRD_PLAN.md +93 -0
  55. package/hosts/zcode/packages/templates/PERGUNTAS_EM_ABERTO_TEMPLATE.md +139 -0
  56. package/hosts/zcode/packages/templates/PLAN_TEMPLATE.md +146 -0
  57. package/hosts/zcode/packages/templates/PRD_TEMPLATE.md +150 -0
  58. package/hosts/zcode/packages/templates/STATE_FILE_SCHEMA.md +56 -0
  59. package/hosts/zcode/skills/_shared/references/stack-profiles.md +72 -0
  60. package/hosts/zcode/skills/_shared/scripts/document_quality.mjs +288 -0
  61. package/hosts/zcode/skills/atlas-audit/SKILL.md +201 -0
  62. package/hosts/zcode/skills/atlas-audit/agents/openai.yaml +7 -0
  63. package/hosts/zcode/skills/atlas-backlog-generator/SKILL.md +93 -0
  64. package/hosts/zcode/skills/atlas-backlog-generator/agents/openai.yaml +4 -0
  65. package/hosts/zcode/skills/atlas-direct-execute/SKILL.md +221 -0
  66. package/hosts/zcode/skills/atlas-direct-execute/agents/openai.yaml +7 -0
  67. package/hosts/zcode/skills/atlas-findings-repair/SKILL.md +158 -0
  68. package/hosts/zcode/skills/atlas-findings-repair/agents/openai.yaml +7 -0
  69. package/hosts/zcode/skills/atlas-plan-execute/SKILL.md +175 -0
  70. package/hosts/zcode/skills/atlas-plan-execute/agents/openai.yaml +7 -0
  71. package/hosts/zcode/skills/atlas-plan-execute/references/plan-contract.md +88 -0
  72. package/hosts/zcode/skills/atlas-plan-execute/references/quality-gates.md +60 -0
  73. package/hosts/zcode/skills/atlas-plan-execute/scripts/check_budget_state.py +96 -0
  74. package/hosts/zcode/skills/atlas-plan-execute/scripts/extract_plan_contract.py +191 -0
  75. package/hosts/zcode/skills/atlas-plan-execute/scripts/validate_gate_result.py +56 -0
  76. package/hosts/zcode/skills/atlas-plan-handoff/SKILL.md +183 -0
  77. package/hosts/zcode/skills/atlas-plan-handoff/agents/openai.yaml +7 -0
  78. package/hosts/zcode/skills/atlas-prd-interview/SKILL.md +82 -0
  79. package/hosts/zcode/skills/atlas-prd-interview/agents/openai.yaml +7 -0
  80. package/hosts/zcode/skills/atlas-slice-review/SKILL.md +156 -0
  81. package/hosts/zcode/skills/atlas-slice-review/agents/openai.yaml +4 -0
  82. package/hosts/zcode/skills/atlas-slice-review/references/review-contract.md +58 -0
  83. package/hosts/zcode/skills/atlas-slice-review/references/scenario-lenses.md +57 -0
  84. package/hosts/zcode/skills/atlas-slice-review/scripts/classify_findings.mjs +60 -0
  85. package/hosts/zcode/skills/atlas-slice-review/scripts/classify_findings.py +24 -0
  86. package/hosts/zcode/skills/atlas-slice-review/scripts/extract_review_slice.py +158 -0
  87. package/hosts/zcode/skills/atlas-sprint-prd-generator/SKILL.md +77 -0
  88. package/hosts/zcode/skills/atlas-sprint-prd-generator/agents/openai.yaml +7 -0
  89. package/hosts/zcode/skills/atlas-task-validator/SKILL.md +179 -0
  90. package/hosts/zcode/skills/atlas-task-validator/agents/openai.yaml +7 -0
  91. package/hosts/zcode/skills/atlas-workflow-orchestrator/SKILL.md +411 -0
  92. package/package.json +1 -1
  93. package/plugins/atlas-workflow-orchestrator/.codex-plugin/plugin.json +5 -4
  94. package/plugins/atlas-workflow-orchestrator/VERSION +1 -1
  95. package/plugins/atlas-workflow-orchestrator/orchestrator/README.md +15 -2
  96. package/plugins/atlas-workflow-orchestrator/orchestrator/commands/workflow.md +7 -5
  97. package/plugins/atlas-workflow-orchestrator/orchestrator/references/host-adapters.md +13 -12
  98. package/plugins/atlas-workflow-orchestrator/orchestrator/references/subagent_dispatch.md +11 -1
  99. package/plugins/atlas-workflow-orchestrator/orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
  100. package/plugins/atlas-workflow-orchestrator/packages/mcp-server/README.md +2 -2
  101. package/plugins/atlas-workflow-orchestrator/packages/mcp-server/package.json +1 -1
  102. package/plugins/atlas-workflow-orchestrator/packages/mcp-server/server.js +149 -21
  103. package/plugins/atlas-workflow-orchestrator/packages/skills/_shared/references/stack-profiles.md +36 -0
  104. package/plugins/atlas-workflow-orchestrator/packages/skills/_shared/scripts/document_quality.mjs +37 -1
  105. package/plugins/atlas-workflow-orchestrator/packages/skills/atlas-audit/SKILL.md +201 -0
  106. package/plugins/atlas-workflow-orchestrator/packages/skills/atlas-audit/agents/openai.yaml +7 -0
  107. package/plugins/atlas-workflow-orchestrator/packages/skills/atlas-task-validator/SKILL.md +6 -0
  108. package/plugins/atlas-workflow-orchestrator/skills/_shared/references/stack-profiles.md +36 -0
  109. package/plugins/atlas-workflow-orchestrator/skills/_shared/scripts/document_quality.mjs +37 -1
  110. package/plugins/atlas-workflow-orchestrator/skills/atlas-audit/SKILL.md +201 -0
  111. package/plugins/atlas-workflow-orchestrator/skills/atlas-audit/agents/openai.yaml +7 -0
  112. package/plugins/atlas-workflow-orchestrator/skills/atlas-task-validator/SKILL.md +6 -0
  113. package/plugins/atlas-workflow-orchestrator/skills/atlas-workflow-orchestrator/SKILL.md +32 -10
@@ -0,0 +1,88 @@
1
+ # Plan Contract
2
+
3
+ Input plans must follow `atlas-plan-handoff` and align with `PLAN_TEMPLATE.md` / `BOUNDARY_PRD_PLAN.md` (compact template, sections 1–8). Locate both in the Atlas Workflow plugin bundle at `packages/templates/`; do not use workspace-local templates as primary sources.
4
+
5
+ If `packages/templates/PLAN_TEMPLATE.md` or `packages/templates/BOUNDARY_PRD_PLAN.md` is absent from the bundle, stop with a clear `Template canônico ausente: <nome-do-template>` error. Do not fall back silently to old local, vault, or global copies.
6
+
7
+ Legacy 15-section plans (handoff prompt, architecture impact block in PRD, etc.) are **not** the target format.
8
+
9
+ ## Required execution metadata
10
+
11
+ Near the top of the artifact:
12
+
13
+ - `Plan prefix: atlas`
14
+ - `Execution mode: sequencial (T01→TN)` | `orchestrated-per-slice`
15
+ - `Executor skill: atlas-plan-execute`
16
+ - `Internal validator: atlas-task-validator`
17
+ - `External review: atlas-slice-review` (optional)
18
+
19
+ ## Required plan sections (match by meaning)
20
+
21
+ | § | Purpose |
22
+ |---|---------|
23
+ | 1 | Executive translation (`Tradução executiva`) — scope link to PRD, reference module, diffs vs mirror |
24
+ | 2 | Execution invariants (derived from `PRD §3` — cite D* IDs, do not paste full table) |
25
+ | 3 | Pitfalls (anti-pattern → fix) |
26
+ | 4 | State at sprint opening (3–6 bullets; not a global file inventory) |
27
+ | 5 | Execution tasks `#### T01.` … `TNN` |
28
+ | 6 | Technical contracts (only where PRD → code is ambiguous) |
29
+ | 8 | Validation and validator checklist (derived from `PRD §6` + §2 invariants) |
30
+
31
+ Section 7 (Slices) is required only when `execution_mode: orchestrated-per-slice`.
32
+
33
+ **Not required:** handoff prompt, planner readiness gate, full `project-rules` rules dump, full PRD scope copy, global touched-files inventory.
34
+
35
+ **Optional:** section 9 open questions / real blockers (executor must stop if active blockers remain).
36
+
37
+ ## Minimum task shape (section 5)
38
+
39
+ Each `#### TNN.` should include when applicable:
40
+
41
+ - `Objetivo` / `Objective`
42
+ - `Referência` (module or pattern — not a long path laundry list)
43
+ - `Pré-condições` / `Preconditions`
44
+ - `Mudança esperada` / `Expected change`
45
+ - `Invariantes preservados`
46
+ - `Não mudar` / `Não fazer` / `Do not do`
47
+ - `Dependências` / `Dependencies`
48
+ - `Riscos` (if not obvious)
49
+ - `Critério de done` / `Done criteria`
50
+ - `Validação local` / `Task-local validation` (command with package path)
51
+ - `Quality gates` (optional on critical tasks)
52
+ - `Casos mínimos` (test tasks only)
53
+
54
+ Paths may appear in **Referência** or **Validação local**; prefer module-level pointers per boundary policy.
55
+
56
+ ## Executor consumption map
57
+
58
+ | Contract need | Plan section |
59
+ |---------------|--------------|
60
+ | Translation, PRD links, reference module | §1 |
61
+ | Execution invariants | §2 |
62
+ | Pitfalls | §3 |
63
+ | Current codebase state | §4 |
64
+ | Tasks, done criteria, local validation | §5 |
65
+ | Technical contracts | §6 |
66
+ | Slice boundaries | §7 (orchestrated mode) |
67
+ | Validator checklist | §8 |
68
+ | Business acceptance (when §8 is thin) | PRD §4–6 (read PRD path from plan header) |
69
+
70
+ ## Why this matters
71
+
72
+ Prefix and mode are part of the execution contract, not chat memory.
73
+
74
+ If `Plan prefix` or `Execution mode` is missing, stop — do not guess the chain.
75
+
76
+ Thin tasks (`refactor bootstrap` only) are not ready for gated execution; ask for a denser plan.
77
+
78
+ Pitfalls, contracts, and invariants are binding — not commentary.
79
+
80
+ ## Parsing notes
81
+
82
+ The bundled `extract_plan_contract.py` uses heading heuristics:
83
+
84
+ - `#` … `####` headings
85
+ - task headings `#### T01. …`
86
+ - bullet lines `- …`
87
+
88
+ Normalize non-standard plans before execution or extend the parser aliases.
@@ -0,0 +1,60 @@
1
+ # Quality Gates
2
+
3
+ Choose the lightest gate that still protects the current task.
4
+
5
+ ## Gate selection order
6
+
7
+ 1. Prove the task with deterministic checks.
8
+ 2. Add semantic review against plan invariants.
9
+ 3. Add targeted runtime verification only when behavior changed in a way static checks cannot prove.
10
+ 4. Escalate to broader validation only when the task blast radius justifies it.
11
+
12
+ ## Common gate matrix
13
+
14
+ ### Pure refactor
15
+
16
+ - targeted tests for touched modules
17
+ - typecheck or analyze for touched package
18
+ - diff scan for forbidden scope expansion
19
+
20
+ ### Contract or DTO change
21
+
22
+ - compilation or typecheck
23
+ - serialization or mapper tests if available
24
+ - search for all consumers of renamed or reshaped fields
25
+ - compare with plan constraints and declared contract
26
+ - verify generated artifacts or localization files named by the plan before wiring consumers
27
+
28
+ ### UI-only change
29
+
30
+ - component, widget, or snapshot tests when available
31
+ - targeted runtime verification for changed flow
32
+ - search for accessibility or localization regressions if the repo has such rules
33
+ - verify role/permission gating when the plan distinguishes who can see or mutate related resources
34
+
35
+ ### State management or orchestration change
36
+
37
+ - focused tests around the changed store, controller, or service
38
+ - validation of loading, error, and success transitions
39
+ - explicit invariant review so closed architectural decisions are not violated
40
+ - rapid repeat-action or stale async check when the slice changes user-triggered operations
41
+
42
+ ### Data migration or cleanup
43
+
44
+ - migration-specific validation
45
+ - idempotency or rollback reasoning
46
+ - stronger stop conditions if external systems are involved
47
+
48
+ ## What not to do
49
+
50
+ - Do not run every available check after every edit.
51
+ - Do not promote unrelated warnings into mandatory work.
52
+ - Do not claim semantic safety from lint alone.
53
+ - Do not keep retrying the same failing check with no code or environment change.
54
+ - Do not repair by weakening a permission matrix, source-of-truth decision, or explicit negative scope.
55
+
56
+ ## Failure classification
57
+
58
+ - `pass`: checks passed and no unresolved high-severity invariant break remains
59
+ - `fixable`: a current-diff issue is clear and repair budget remains
60
+ - `blocked`: repair would require scope change, external dependency, environment fix, or repeated speculative retries
@@ -0,0 +1,96 @@
1
+ #!/usr/bin/env python3
2
+ """Track bounded repair attempts for a gated execution task."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import pathlib
9
+ from dataclasses import dataclass, asdict
10
+
11
+
12
+ @dataclass
13
+ class BudgetState:
14
+ task_id: str
15
+ max_attempts: int = 2
16
+ max_same_failure: int = 2
17
+ attempts: int = 0
18
+ same_failure_count: int = 0
19
+ last_failure_key: str = ""
20
+ blocked: bool = False
21
+
22
+
23
+ def load_state(path: pathlib.Path) -> BudgetState:
24
+ if not path.exists():
25
+ raise FileNotFoundError(f"State file not found: {path}")
26
+ return BudgetState(**json.loads(path.read_text(encoding="utf-8")))
27
+
28
+
29
+ def save_state(path: pathlib.Path, state: BudgetState) -> None:
30
+ path.parent.mkdir(parents=True, exist_ok=True)
31
+ path.write_text(json.dumps(asdict(state), indent=2) + "\n", encoding="utf-8")
32
+
33
+
34
+ def cmd_init(args: argparse.Namespace) -> int:
35
+ state = BudgetState(
36
+ task_id=args.task_id,
37
+ max_attempts=args.max_attempts,
38
+ max_same_failure=args.max_same_failure,
39
+ )
40
+ save_state(pathlib.Path(args.state_file), state)
41
+ print(json.dumps(asdict(state), indent=2))
42
+ return 0
43
+
44
+
45
+ def cmd_record(args: argparse.Namespace) -> int:
46
+ path = pathlib.Path(args.state_file)
47
+ state = load_state(path)
48
+ state.attempts += 1
49
+
50
+ if args.failure_key:
51
+ if args.failure_key == state.last_failure_key:
52
+ state.same_failure_count += 1
53
+ else:
54
+ state.last_failure_key = args.failure_key
55
+ state.same_failure_count = 1
56
+
57
+ if state.attempts >= state.max_attempts or state.same_failure_count >= state.max_same_failure:
58
+ state.blocked = True
59
+
60
+ save_state(path, state)
61
+ print(json.dumps(asdict(state), indent=2))
62
+ return 0
63
+
64
+
65
+ def cmd_status(args: argparse.Namespace) -> int:
66
+ state = load_state(pathlib.Path(args.state_file))
67
+ print(json.dumps(asdict(state), indent=2))
68
+ return 0
69
+
70
+
71
+ def main() -> int:
72
+ parser = argparse.ArgumentParser(description=__doc__)
73
+ subparsers = parser.add_subparsers(dest="command", required=True)
74
+
75
+ init_parser = subparsers.add_parser("init")
76
+ init_parser.add_argument("state_file")
77
+ init_parser.add_argument("task_id")
78
+ init_parser.add_argument("--max-attempts", type=int, default=2)
79
+ init_parser.add_argument("--max-same-failure", type=int, default=2)
80
+ init_parser.set_defaults(func=cmd_init)
81
+
82
+ record_parser = subparsers.add_parser("record")
83
+ record_parser.add_argument("state_file")
84
+ record_parser.add_argument("--failure-key", default="")
85
+ record_parser.set_defaults(func=cmd_record)
86
+
87
+ status_parser = subparsers.add_parser("status")
88
+ status_parser.add_argument("state_file")
89
+ status_parser.set_defaults(func=cmd_status)
90
+
91
+ args = parser.parse_args()
92
+ return args.func(args)
93
+
94
+
95
+ if __name__ == "__main__":
96
+ raise SystemExit(main())
@@ -0,0 +1,191 @@
1
+ #!/usr/bin/env python3
2
+ """Extract execution-relevant sections from a atlas-plan-handoff markdown artifact."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import pathlib
9
+ import re
10
+ import sys
11
+ from typing import Any
12
+
13
+ HEADING_RE = re.compile(r"^(#{1,4})\s+(.*\S)\s*$")
14
+ TASK_RE = re.compile(r"^T\d{2}\.\s+")
15
+
16
+
17
+ def normalize_heading(text: str) -> str:
18
+ text = re.sub(r"^\d+\.\s*", "", text.strip())
19
+ text = re.sub(r"\(§\d+\)", "", text, flags=re.IGNORECASE)
20
+ return re.sub(r"[^a-z0-9]+", "_", text.lower()).strip("_")
21
+
22
+
23
+ def has_any(summary: dict[str, list[str]], keys: list[str]) -> bool:
24
+ return any(key in summary for key in keys)
25
+
26
+
27
+ def first_section(summary: dict[str, list[str]], keys: list[str]) -> list[str]:
28
+ for key in keys:
29
+ if key in summary:
30
+ return summary[key]
31
+ return []
32
+
33
+
34
+ def parse_plan(text: str) -> dict[str, Any]:
35
+ sections: list[dict[str, Any]] = []
36
+ current: dict[str, Any] | None = None
37
+
38
+ for raw_line in text.splitlines():
39
+ line = raw_line.rstrip()
40
+ match = HEADING_RE.match(line)
41
+ if match:
42
+ level = len(match.group(1))
43
+ title = match.group(2).strip()
44
+ current = {
45
+ "level": level,
46
+ "title": title,
47
+ "key": normalize_heading(title),
48
+ "lines": [],
49
+ }
50
+ sections.append(current)
51
+ continue
52
+ if current is not None:
53
+ current["lines"].append(line)
54
+
55
+ tasks = []
56
+ for section in sections:
57
+ if section["level"] == 4 and TASK_RE.match(section["title"]):
58
+ tasks.append(
59
+ {
60
+ "id": section["title"].split(".", 1)[0],
61
+ "title": section["title"],
62
+ "body": [line for line in section["lines"] if line.strip()],
63
+ }
64
+ )
65
+
66
+ summary = {section["key"]: [line for line in section["lines"] if line.strip()] for section in sections}
67
+ metadata = {
68
+ "plan_prefix": "",
69
+ "execution_mode": "",
70
+ "executor_skill": "",
71
+ "internal_validator": "",
72
+ "external_review": "",
73
+ }
74
+
75
+ metadata_section = first_section(
76
+ summary,
77
+ ["execution_metadata", "metadados_de_execu_o", "metadados_execu_o"],
78
+ )
79
+ for line in metadata_section:
80
+ lowered = line.lower()
81
+ if "plan prefix" in lowered:
82
+ metadata["plan_prefix"] = line.split(":", 1)[-1].strip().strip("`")
83
+ elif "execution mode" in lowered:
84
+ metadata["execution_mode"] = line.split(":", 1)[-1].strip().strip("`")
85
+ elif "executor skill" in lowered:
86
+ metadata["executor_skill"] = line.split(":", 1)[-1].strip().strip("`")
87
+ elif "internal validator" in lowered:
88
+ metadata["internal_validator"] = line.split(":", 1)[-1].strip().strip("`")
89
+ elif "external review" in lowered:
90
+ metadata["external_review"] = line.split(":", 1)[-1].strip().strip("`")
91
+
92
+ # Compact PLAN_TEMPLATE (sections 1–8); legacy aliases kept for older artifacts.
93
+ required_groups = {
94
+ "execution_metadata": ["execution_metadata", "metadados_de_execu_o", "metadados_execu_o"],
95
+ "executive_translation": [
96
+ "tradu_o_executiva",
97
+ "executive_summary",
98
+ "executive_translation",
99
+ "resumo_executivo",
100
+ ],
101
+ "execution_invariants": [
102
+ "invariantes_de_execu_o",
103
+ "invariantes_de_execu_o_derivados_do_prd",
104
+ "execution_invariants",
105
+ ],
106
+ "pitfalls": ["pitfalls"],
107
+ "sprint_opening_state": [
108
+ "estado_na_abertura_da_sprint",
109
+ "estado_na_abertura_da_sprint_pr_implementa_o",
110
+ "current_state_relevant_to_execution",
111
+ "estado_atual_relevante_para_execu_o",
112
+ ],
113
+ "execution_tasks": ["tarefas_de_execu_o", "execution_tasks", "tarefas"],
114
+ "technical_contracts": [
115
+ "contratos_t_cnicos",
116
+ "contratos_t_cnicos_s_ambiguidade_prd_c_digo",
117
+ "technical_contracts",
118
+ ],
119
+ "validation_checklist": [
120
+ "valida_o_e_checklist",
121
+ "valida_o_e_checklist_validator",
122
+ "validation_and_checklist",
123
+ "validation",
124
+ "valida_o",
125
+ "valida_o_final",
126
+ ],
127
+ }
128
+
129
+ optional_groups = {
130
+ "slices": ["slices", "slices_somente_se_execution_mode_orchestrated_per_slice"],
131
+ "open_questions_blockers": [
132
+ "perguntas_em_aberto_e_bloqueios_reais",
133
+ "open_questions_and_real_blockers",
134
+ "open_questions",
135
+ "real_blockers",
136
+ ],
137
+ # Legacy sections — extracted if present, never required.
138
+ "handoff_prompt": ["handoff_prompt", "executor_guidance"],
139
+ "legacy_scope": ["scope", "escopo"],
140
+ "legacy_architecture": [
141
+ "solution_design_and_architecture",
142
+ "design_e_arquitetura_da_solu_o",
143
+ ],
144
+ }
145
+
146
+ missing = [name for name, aliases in required_groups.items() if not has_any(summary, aliases)]
147
+
148
+ execution_mode = metadata.get("execution_mode", "").lower()
149
+ if "orchestrated" in execution_mode and not has_any(summary, optional_groups["slices"]):
150
+ missing.append("slices")
151
+
152
+ return {
153
+ "sections": [
154
+ {"title": section["title"], "key": section["key"], "level": section["level"]}
155
+ for section in sections
156
+ ],
157
+ "tasks": tasks,
158
+ "missing_required_sections": missing,
159
+ "execution_metadata": metadata,
160
+ "summary": {
161
+ "execution_metadata": metadata_section,
162
+ "executive_translation": first_section(summary, required_groups["executive_translation"]),
163
+ "execution_invariants": first_section(summary, required_groups["execution_invariants"]),
164
+ "pitfalls": first_section(summary, required_groups["pitfalls"]),
165
+ "sprint_opening_state": first_section(summary, required_groups["sprint_opening_state"]),
166
+ "execution_tasks": first_section(summary, required_groups["execution_tasks"]),
167
+ "technical_contracts": first_section(summary, required_groups["technical_contracts"]),
168
+ "validation_checklist": first_section(summary, required_groups["validation_checklist"]),
169
+ "slices": first_section(summary, optional_groups["slices"]),
170
+ "open_questions_blockers": first_section(
171
+ summary, optional_groups["open_questions_blockers"]
172
+ ),
173
+ "handoff_prompt": first_section(summary, optional_groups["handoff_prompt"]),
174
+ },
175
+ }
176
+
177
+
178
+ def main() -> int:
179
+ parser = argparse.ArgumentParser(description=__doc__)
180
+ parser.add_argument("plan", help="Path to a markdown plan artifact")
181
+ args = parser.parse_args()
182
+
183
+ plan_path = pathlib.Path(args.plan)
184
+ payload = parse_plan(plan_path.read_text(encoding="utf-8"))
185
+ json.dump(payload, sys.stdout, indent=2)
186
+ sys.stdout.write("\n")
187
+ return 0
188
+
189
+
190
+ if __name__ == "__main__":
191
+ raise SystemExit(main())
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env python3
2
+ """Classify a gate outcome into pass, fixable, or blocked."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import pathlib
9
+ import sys
10
+ from typing import Any
11
+
12
+
13
+ def load_json(path: pathlib.Path) -> dict[str, Any]:
14
+ if not path.exists():
15
+ raise FileNotFoundError(f"JSON file not found: {path}")
16
+ return json.loads(path.read_text(encoding="utf-8"))
17
+
18
+
19
+ def main() -> int:
20
+ parser = argparse.ArgumentParser(description=__doc__)
21
+ parser.add_argument("gate_result", help="JSON file describing the gate outcome")
22
+ parser.add_argument("--budget-state", help="Optional budget state JSON file")
23
+ args = parser.parse_args()
24
+
25
+ try:
26
+ payload = load_json(pathlib.Path(args.gate_result))
27
+ budget = load_json(pathlib.Path(args.budget_state)) if args.budget_state else {}
28
+ except FileNotFoundError as exc:
29
+ sys.stderr.write(f"{exc}\n")
30
+ return 1
31
+
32
+ failed_checks = payload.get("failed_checks", [])
33
+ invariant_breaks = payload.get("invariant_breaks", [])
34
+ external_blockers = payload.get("external_blockers", [])
35
+ diff_attributed = payload.get("diff_attributed", True)
36
+
37
+ if external_blockers or budget.get("blocked"):
38
+ status = "blocked"
39
+ elif failed_checks or invariant_breaks:
40
+ status = "fixable" if diff_attributed else "blocked"
41
+ else:
42
+ status = "pass"
43
+
44
+ result = {
45
+ "status": status,
46
+ "failed_checks": failed_checks,
47
+ "invariant_breaks": invariant_breaks,
48
+ "external_blockers": external_blockers,
49
+ "diff_attributed": diff_attributed,
50
+ }
51
+ print(json.dumps(result, indent=2))
52
+ return 0
53
+
54
+
55
+ if __name__ == "__main__":
56
+ raise SystemExit(main())
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: atlas-plan-handoff
3
+ description: Skill `atlas-plan-handoff`. Produz um handoff executável da família Atlas, fechando prefixo, modo de execução e gates no próprio artefato para consumo por `atlas-plan-execute` e `atlas-slice-review`.
4
+ ---
5
+
6
+ # Atlas Plan Handoff
7
+
8
+ Use esta skill quando o usuário pedir um plano executável da cadeia `atlas-*`.
9
+
10
+ O artefato segue `PLAN_TEMPLATE.md` e `BOUNDARY_PRD_PLAN.md` — **localize ambos em `<raiz-do-plugin>/packages/templates/`**. O plano **não** depende de memória do chat para prefixo, modo ou executor.
11
+
12
+ ## Resolução Canônica de Templates
13
+
14
+ * Fonte única: `packages/templates/` empacotado no plugin Atlas Workflow.
15
+ * Resolver `PLAN_TEMPLATE.md` e `BOUNDARY_PRD_PLAN.md` a partir da raiz do plugin/bundle, antes de olhar qualquer arquivo do repo consumidor.
16
+ * Template local do repo consumidor nunca sobrepõe o template empacotado.
17
+ * Se `packages/templates/PLAN_TEMPLATE.md` ou `packages/templates/BOUNDARY_PRD_PLAN.md` não existir, abortar com erro claro: `Template canônico ausente: <nome-do-template>`.
18
+ * Não usar fallback silencioso para cópias antigas, vault local ou templates globais.
19
+
20
+ ## State persistence
21
+
22
+ Use `atlas_run_state` como fonte primária de estado da run. Não leia/escreva estado por file IO direto. Se o MCP estiver indisponível, avise que o gate não pode ser comprovado e aborte a fase em vez de seguir por fallback narrativo.
23
+
24
+ ## Plan path resolution
25
+
26
+ Os paths são fornecidos pelo adapter de host: consultar `atlas_capabilities` e ler `plan_paths` (`write` + `read_order`). Referência canônica: `packages/orchestrator/references/host-adapters.md`. Valores atuais (iguais em todo host):
27
+
28
+ Escrita de novos planos: somente `.atlas/plans/`.
29
+
30
+ Leitura/migração por 1 release (ordem de `plan_paths.read_order`):
31
+
32
+ 1. `.atlas/plans/`
33
+ 2. `.cursor/plans/` com warning de depreciação
34
+ 3. `.codex/plans/` com warning de depreciação
35
+
36
+ Se um plano legado for lido, o próximo artefato gerado deve ser salvo em `.atlas/plans/`.
37
+
38
+ ## Cadeia de execução
39
+
40
+ ```text
41
+ atlas-plan-handoff → atlas-plan-execute → atlas-task-validator → atlas-slice-review (opcional, via `--review`)
42
+ ```
43
+
44
+ No workflow `full`, `atlas-plan-handoff` é autoria documental do agente principal/orquestrador. O primeiro sub-agent da cadeia só nasce em `atlas-plan-execute`.
45
+
46
+ ---
47
+
48
+ ## Fluxo obrigatório
49
+
50
+ 1. **Classificação da tarefa:** feature, ui, contract, navigation, shared, security, diagnostic, refactoring, testing. Leia instruções reais aplicáveis do repo; `project-rules/` é apenas um formato possível, nunca requisito universal.
51
+ 2. **Grounding no código:** confirme padrões, contratos, manifests e comandos reais antes de inferir. Resolva baseline/perfis via `../_shared/references/stack-profiles.md` + `detectStackProfiles(project_root, declared_commands, boundary_paths)`; não presuma Flutter nem aplique perfil fora do package correspondente.
52
+ 3. **Decisões estáveis:** sanar bloqueios com perguntas ao usuário; registrar no plano (não recopiar tabela D* do PRD — referenciar `PRD §3`).
53
+ 4. **Escrita:** artefato markdown no path canônico `.atlas/plans/`. Teto orientativo ~250–350 linhas (até ~450 com slices).
54
+
55
+ ---
56
+
57
+ ## Metadados obrigatórios (topo do artefato)
58
+
59
+ ```md
60
+ ## Metadados de execução
61
+ - Plan prefix: `atlas`
62
+ - Execution mode: `sequencial (T01→TN)` | `orchestrated-per-slice`
63
+ - Executor skill: `atlas-plan-execute`
64
+ - Internal validator: `atlas-task-validator`
65
+ - External review: `atlas-slice-review` (optional)
66
+ ```
67
+
68
+ Regras:
69
+
70
+ - `Plan prefix` é sempre `atlas`.
71
+ - Se o modo não estiver decidido, o plano **não** está pronto para execução.
72
+ - Deixe explícito por que o modo escolhido é adequado, checks por task vs fechamento de slice e quando parar em `blocked`.
73
+
74
+ ---
75
+
76
+ ## Estrutura do plano (seções 1 a 8)
77
+
78
+ ### 1. Tradução executiva
79
+
80
+ - O que será implementado e o resultado observável técnico.
81
+ - Padrão de referência no monorepo e tabela **referência vs esta entrega** (ligar a `PRD §3` D*, não recopiar a tabela).
82
+ - Link ao PRD: `PRD §2` escopo, `PRD §3` decisões.
83
+
84
+ ### 2. Invariantes de execução (derivados do PRD)
85
+
86
+ - Invariantes técnicos inegociáveis (ex.: sem refetch ao filtrar).
87
+ - Referenciar IDs: `PRD §3 D12` — não colar a tabela D* inteira.
88
+
89
+ ### 3. Pitfalls
90
+
91
+ - `anti-padrão observado` → `padrão canônico correto` (ancorado no repo).
92
+
93
+ ### 4. Estado na abertura da sprint (pré-implementação)
94
+
95
+ - 3–6 bullets sobre o código hoje (comportamento/ausência — não inventário global de arquivos).
96
+ - Se já implementado: tratar como checklist de verificação.
97
+
98
+ ### 5. Tarefas de execução
99
+
100
+ Tarefas `#### T01.` … `#### TNN.` com schema de `BOUNDARY_PRD_PLAN.md` canônico empacotado:
101
+
102
+ - **Objetivo**
103
+ - **Referência** (módulo/padrão no monorepo — evite listas longas de paths; o executor descobre no repo)
104
+ - **Pré-condições**
105
+ - **Mudança esperada**
106
+ - **Invariantes preservados**
107
+ - **Não mudar** / **Não fazer**
108
+ - **Dependências**
109
+ - **Riscos** (se não óbvio)
110
+ - **Critério de done**
111
+ - **Validação local** (comando com path do package)
112
+ - **Quality gates** (opcional em tasks críticas)
113
+ - **Casos mínimos** (somente em tasks de teste)
114
+
115
+ **Regra de minimalismo estrutural (autoria de task):** ao redigir `Mudança esperada`, prefira a forma mínima viável que cumpre o `Critério de done` — reusar módulo/símbolo já existente no repo antes de introduzir nova abstração; usar stdlib/feature nativa antes de dependência nova; evitar indireção, factory, wrapper, camada ou opção de config não exigida por PRD/invariante. A regra recai **somente** sobre abstração/indireção/arquivo/dependência nova. **Nunca** reduz: validação de trust-boundary, error-handling, data-loss, invariantes §2, cobertura de cenário/teste e negative paths. Em dúvida entre enxuto e seguro, escolha seguro.
116
+
117
+ Última task típica: **Validação final** (checks reais da stack ativa e passos manuais alinhados a **PRD §4–6**). Flutter usa `flutter analyze/test`; Node e Python usam somente scripts/ferramentas declarados no repo/plano.
118
+
119
+ ### 6. Contratos técnicos (só ambiguidade PRD → código)
120
+
121
+ - Assinaturas, shapes e mapeamentos onde o PRD §5 não fecha implementação.
122
+
123
+ ### 7. Slices (somente se `execution_mode: orchestrated-per-slice`)
124
+
125
+ - Tabela: slice, tasks, objetivo, boundary de diff esperado.
126
+
127
+ ### 8. Validação e checklist (validator)
128
+
129
+ - Critérios derivados de **PRD §6** + invariantes **§2** deste plano.
130
+ - Título recomendado: `## 8. Validação e checklist (validator)`.
131
+ - Comandos globais aplicáveis ao package, derivados de manifests/scripts reais; nunca inventar `flutter`, `npm` ou `pytest`.
132
+
133
+ ---
134
+
135
+ ## Seção opcional
136
+
137
+ ### 9. Perguntas em aberto e bloqueios reais
138
+
139
+ - Só bloqueios que impedem execução segura. O executor **para** se houver itens ativos aqui.
140
+ - **Não** confundir com PRD §7 Apêndice (Referências).
141
+
142
+ ---
143
+
144
+ ## O que NÃO incluir (propositalmente)
145
+
146
+ - Handoff prompt final no artefato (o executor lê o arquivo; ver `BOUNDARY_PRD_PLAN.md` no repo ativo).
147
+ - Gate de prontidão do autor do plano.
148
+ - Lista integral de rules do `project-rules` (o executor carrega via `AGENTS.md`).
149
+ - Cópia integral do escopo/fora de escopo do PRD.
150
+ - Inventário global de todos os arquivos tocados.
151
+
152
+ ---
153
+
154
+ ## Uso standalone vs protocolo interno no workflow (PRD D10/D11)
155
+
156
+ Esta skill é de **autoria documental** (redigir um `PLAN_*.md`). A fronteira de determinismo do Atlas é a **mutação de código** (PRD D10): como redigir um plano não muta código, **autoria é livre, execução é gateada**.
157
+
158
+ ### (a) Uso standalone permitido
159
+
160
+ Você pode invocar `atlas-plan-handoff` diretamente, fora do pipeline, para escrever um plano. Não há restrição: autoria documental não muta o produto. O `PLAN_*.md` resultante é livre para existir e ser editado.
161
+
162
+ ### (b) O artefato NÃO é confiável só por existir
163
+
164
+ Um plano escrito standalone **não vale como gate aprovado** só porque existe — nem mesmo com nome `PLAN_*.md`. Ao entrar em execução (modos `full`/`direct`/`execute`), o plano é **re-gateado obrigatoriamente** por `atlas_verify_artifact` + `atlas_verify_template_conformance` (TC); no modo `execute`, essa reverificação na entrada é o equivalente ao gate pós-plano (PRD D13). Plano velho, manual, renomeado ou fora de conformidade **trava na entrada da execução**, não na autoria. Esta skill não declara o plano "executável de forma determinística" só por tê-lo escrito.
165
+
166
+ ### (c) Standalone vs protocolo interno no workflow
167
+
168
+ - **Standalone:** o usuário conduz a skill diretamente; o produto é o `PLAN_*.md`, sujeito a re-validação na entrada de execução.
169
+ - **No workflow:** quem conduz a fase de plano é o **orquestrador principal** (agente principal), que despacha/autora o plano antes de validá-lo e roda os gates MCP. Uma vez que o plano passa `atlas_verify_artifact` + TC, o orquestrador fica de mãos atadas (não edita mais o plano). A skill é a mesma; o que muda é quem orquestra e os gates que cercam a fase.
170
+
171
+ > **Invariante:** autoria é livre, execução é gateada. Um plano só vira confiável para execução após `atlas_verify_artifact` + TC na entrada (PRD D11).
172
+
173
+ ---
174
+
175
+ ## Consistência da cadeia
176
+
177
+ O próximo agente, só lendo o artefato, deve saber:
178
+
179
+ - usar apenas skills `atlas-*` declaradas nos metadados;
180
+ - respeitar `execution_mode`;
181
+ - rodar `atlas-task-validator` antes de fechar a slice;
182
+ - usar `atlas-slice-review` como segunda camada fria, não substituto do validator interno;
183
+ - cruzar aceite de negócio com **PRD §4–6** quando o checklist do §8 for fino.
@@ -0,0 +1,7 @@
1
+ interface:
2
+ display_name: "Atlas Plan Handoff"
3
+ short_description: "Handoff executável da família atlas-* com prefixo e modo fechados"
4
+ default_prompt: "Use $atlas-plan-handoff para produzir um plano executável da cadeia atlas-* com prefixo fechado, execution mode explícito, executor correto, validator interno obrigatório e review externo opcional."
5
+
6
+ policy:
7
+ allow_implicit_invocation: true