feat: stack development in three phases - stack-dev (design), stack-build, stack-close, handed over through tracker states (#168)
CI / verify (push) Successful in 5m15s
CI / pwsh (push) Successful in 2m2s
Release / release (push) Successful in 34s

stack-build and stack-close carry disable-model-invocation, so each phase change is
the operator's slash command; no skill offers a mid-session /model or /effort switch.
Mode rules and the phase table move to instructions/dev/stack-mode.md, publish and CI
waiting to instructions/dev/publish-and-ci.md, the ready definition to issue-tracking.md.

Files changed:
- AGENTS.md
- CHANGES.md
- DEVELOPMENT.md
- README.md
- VERSION
- docs/model-and-effort-selection.md
- instructions/CONTRACT.md
- instructions/dev/commonplace-kb.md
- instructions/dev/dev-setup.md
- instructions/dev/doc-pull-through.md
- instructions/dev/issue-tracking.md
- instructions/dev/publish-and-ci.md
- instructions/dev/stack-build/SKILL.md
- instructions/dev/stack-close/SKILL.md
- instructions/dev/stack-dev/SKILL.md
- instructions/dev/stack-mode.md
- instructions/dev/testing-conventions.md
- instructions/dev/version-parts.md
- tools/chemenu/commands/git_publish.py
- tools/chemenu/tests/test_git_publish.py
- tools/chemenu/tests/test_instructions_cmd.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
This commit is contained in:
torbenandClaude Opus 5.5 committed 2026-10-02 20:33:07 +02:00
1 parent 80488bee38
commit d8224ee2ab
21 files changed
+631 -331

No files matched your search

+12 -1
View File
@@ -395,7 +395,7 @@ def test_below_threshold_publish_goes_straight_through(repo):
def test_publish_notes_stack_machinery_after_success(repo, capsys):
"""The closing-phase reminder lands exactly once, after the OK line, and
"""The CI-then-closing-phase reminder lands exactly once, after the OK line, and
only when the changeset actually falls under version-parts.md's scope."""
(repo / "instructions").mkdir()
(repo / "instructions/example.md").write_text("x\n", encoding="utf-8")
@@ -405,6 +405,17 @@ def test_publish_notes_stack_machinery_after_success(repo, capsys):
assert out.count(STACK_MACHINERY_NOTE) == 1
def test_stack_machinery_note_puts_ci_before_the_unchecked_phase():
"""A stack publish is followed by CI first - a mechanical check - and only
after a green run by the phase nothing checks. The note must not claim the
unchecked phase starts right at the publish (#168): that sent CI waiting
into the closing phase, where a red run turned it back into a build."""
ci = STACK_MACHINERY_NOTE.find("CI")
unchecked = STACK_MACHINERY_NOTE.find("covered by no tool")
assert ci != -1 and unchecked != -1
assert ci < unchecked
def test_publish_stays_quiet_for_ordinary_content(repo, capsys):
_write_files(repo, 1)
_publish(message="ordinary content")
+17 -1
View File
@@ -64,7 +64,7 @@ def test_the_real_repo_publishes_every_skill():
"""Guards the actual layout, not a fixture: these are the skills the
harness is expected to offer, one per naming family - `wiki-` for the
knowledge pipeline, `gtd-` for the commitment layer, `stack-` for the
stack's own development. The `stack-` pair is nested under
stack's own development. The `stack-` trio is nested under
instructions/dev/, discovered the same way as the top-level ones."""
names = {p.name for p in instructions_cmd.skill_dirs()}
assert {
@@ -75,10 +75,26 @@ def test_the_real_repo_publishes_every_skill():
"wiki-status",
"gtd-weekly-review",
"stack-dev",
"stack-build",
"stack-close",
} <= names
def test_only_the_operator_starts_the_build_and_close_phases():
"""#168: the phase changes are the operator's slash command, so
`stack-build` and `stack-close` carry `disable-model-invocation: true`,
while `stack-dev` - the entry point the harness has to find on its own -
does not. `sync` copies the frontmatter byte for byte, which the drift
check in `verify` already holds the published copies to."""
skills = {p.name: p for p in instructions_cmd.skill_dirs()}
flags = {}
for name in ("stack-dev", "stack-build", "stack-close"):
frontmatter, error = instructions_cmd._read_frontmatter(skills[name] / "SKILL.md")
assert frontmatter is not None, error
flags[name] = frontmatter.get("disable-model-invocation", False)
assert flags == {"stack-dev": False, "stack-build": True, "stack-close": True}
_NO_PROVIDER_FORBIDDEN_TERMS = [
"super productivity",
"azure devops",