fix: Eliminate race condition by letting automation generate discussion files
Changed setup_project.py to only create request.md during setup, allowing the pre-commit hook automation to generate discussion and summary files. Problem (before): - setup_project.py created request.md, feature.discussion.md, and .sum.md - git commit staged ALL files and triggered pre-commit hook - runner.py saw request.md and tried to generate feature.discussion.md - But feature.discussion.md was already in the index → race condition - workflow.py also tried to update .sum.md → more conflicts Solution (now): - setup_project.py creates ONLY request.md - discussions/ directory is created but empty - First commit triggers automation: - runner.py sees request.md → generates feature.discussion.md (AI) - ensure_summary in pre-commit hook → creates .sum.md from template - workflow.py → updates .sum.md with vote data - No more conflicts between setup and automation Benefits: 1. No race condition - each file has one source of truth 2. Actually exercises the automation system on first commit 3. Generated files always match current automation rules 4. Simpler setup code (67 lines removed) Testing: The automation will now properly run on first commit instead of conflicting with pre-seeded files. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
70c3f6f80d
commit
80c9345e16
|
|
@ -246,13 +246,22 @@ def seed_process_and_rules(target: Path):
|
|||
copy_if_missing(t_rules_features, rules_dir / ".ai-rules.yml")
|
||||
|
||||
def seed_initial_feature(target: Path, req_fields: dict | None):
|
||||
"""
|
||||
Create the initial feature request file.
|
||||
|
||||
This function ONLY creates request.md - the automation system will generate
|
||||
the discussion and summary files when request.md is committed.
|
||||
|
||||
This avoids race conditions where setup tries to create files that the
|
||||
pre-commit hook also wants to generate.
|
||||
"""
|
||||
today = datetime.date.today().isoformat()
|
||||
feature_id = f"FR_{today}_initial-feature-request"
|
||||
fr_dir = target / "Docs" / "features" / feature_id
|
||||
disc_dir = fr_dir / "discussions"
|
||||
disc_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Gather values from Ramble result (if any)
|
||||
# Gather values from the Ramble result (if any)
|
||||
fields = (req_fields or {}).get("fields", {}) if req_fields else {}
|
||||
# Load FR template + META
|
||||
fr_tmpl = INSTALL_ROOT / "assets" / "templates" / "feature_request.md"
|
||||
|
|
@ -286,69 +295,21 @@ def seed_initial_feature(target: Path, req_fields: dict | None):
|
|||
**Meta**: Created: {today}
|
||||
"""
|
||||
|
||||
# Write ONLY request.md - let automation generate the rest
|
||||
(fr_dir / "request.md").write_text(render_placeholders(fr_body, values), encoding="utf-8")
|
||||
|
||||
# --- feature.discussion.md ---
|
||||
disc_tmpl = INSTALL_ROOT / "assets" / "templates" / "feature.discussion.md"
|
||||
d_meta, d_body = load_template_with_meta(disc_tmpl)
|
||||
# Always include the front-matter for rules, then template body (or fallback)
|
||||
fm = f"""---\ntype: discussion\nstage: feature\nstatus: OPEN\nfeature_id: {feature_id}\ncreated: {today}\n---\n"""
|
||||
if not d_body.strip():
|
||||
d_body = (
|
||||
"## Summary\n"
|
||||
f"Initial discussion for {feature_id}. Append your comments below.\n\n"
|
||||
"## Participation\n"
|
||||
"- Maintainer: Kickoff. VOTE: READY\n"
|
||||
)
|
||||
(disc_dir / "feature.discussion.md").write_text(fm + render_placeholders(d_body, values), encoding="utf-8")
|
||||
|
||||
# --- feature.discussion.sum.md ---
|
||||
sum_tmpl = INSTALL_ROOT / "assets" / "templates" / "feature.discussion.sum.md"
|
||||
s_meta, s_body = load_template_with_meta(sum_tmpl)
|
||||
if s_body.strip():
|
||||
# use template
|
||||
(disc_dir / "feature.discussion.sum.md").write_text(render_placeholders(s_body, values), encoding="utf-8")
|
||||
else:
|
||||
# your existing static content
|
||||
(disc_dir / "feature.discussion.sum.md").write_text(
|
||||
"""# Summary — Feature
|
||||
|
||||
<!-- SUMMARY:DECISIONS START -->
|
||||
## Decisions (ADR-style)
|
||||
- (none yet)
|
||||
<!-- SUMMARY:DECISIONS END -->
|
||||
|
||||
<!-- SUMMARY:OPEN_QUESTIONS START -->
|
||||
## Open Questions
|
||||
- (none yet)
|
||||
<!-- SUMMARY:OPEN_QUESTIONS END -->
|
||||
|
||||
<!-- SUMMARY:AWAITING START -->
|
||||
## Awaiting Replies
|
||||
- (none yet)
|
||||
<!-- SUMMARY:AWAITING END -->
|
||||
|
||||
<!-- SUMMARY:ACTION_ITEMS START -->
|
||||
## Action Items
|
||||
- (none yet)
|
||||
<!-- SUMMARY:ACTION_ITEMS END -->
|
||||
|
||||
<!-- SUMMARY:VOTES START -->
|
||||
## Votes (latest per participant)
|
||||
READY: 1 • CHANGES: 0 • REJECT: 0
|
||||
- Maintainer
|
||||
<!-- SUMMARY:VOTES END -->
|
||||
|
||||
<!-- SUMMARY:TIMELINE START -->
|
||||
## Timeline (most recent first)
|
||||
- {ts} Maintainer: Kickoff
|
||||
<!-- SUMMARY:TIMELINE END -->
|
||||
|
||||
<!-- SUMMARY:LINKS START -->
|
||||
## Links
|
||||
- Design/Plan: ../design/design.md
|
||||
<!-- SUMMARY:LINKS END -->
|
||||
""".replace("{ts}", today), encoding="utf-8")
|
||||
# NOTE: We do NOT create feature.discussion.md or feature.discussion.sum.md here.
|
||||
# The pre-commit hook automation will generate these files when request.md is committed.
|
||||
#
|
||||
# This approach:
|
||||
# 1. Avoids race conditions (setup vs. hook both creating same files)
|
||||
# 2. Actually exercises the automation system on first commit
|
||||
# 3. Ensures generated files match current automation rules
|
||||
#
|
||||
# The automation flow will be:
|
||||
# git commit → pre-commit hook → runner.py sees request.md
|
||||
# → generates feature.discussion.md (AI-powered)
|
||||
# → workflow.py generates feature.discussion.sum.md
|
||||
|
||||
|
||||
def copy_install_assets_to_target(target: Path):
|
||||
|
|
|
|||
Loading…
Reference in New Issue