Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/cli-branch-guard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: CLI Branch Guard

on:
pull_request:
branches: [main]

jobs:
check-cli-changes:
runs-on: ubuntu-latest
steps:
- name: Check for CLI changes
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Fail if cli/ changed
run: |
CHANGED_FILES=$(git diff --name-only origin/main...HEAD -- cli/)
if [ -n "$CHANGED_FILES" ]; then
echo "::error::Direct PRs to main cannot include cli/ changes."
echo "::error::CLI changes must go through the 'next' branch first."
echo ""
echo "Changed files in cli/:"
echo "$CHANGED_FILES"
echo ""
echo "To fix: target your PR to 'next' instead of 'main'"
exit 1
fi
echo "No cli/ changes detected. PR can proceed."
25 changes: 20 additions & 5 deletions .specify/memory/constitution.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
<!--
Sync Impact Report
===================
Version change: 1.3.0 -> 1.3.1
Version change: 1.3.1 -> 1.4.0

Modified principles:
- VI. Minimal Code: Added explicit NO DEPRECATED FUNCTIONS, NO BACKWARDS-COMPAT SHIMS,
DELETE TESTS FOR DELETED CODE rules. Updated rationale to emphasize single maintainer.
Modified principles: N/A

Added sections:
- Core Principles V. Dogfooding (1.1.0)
- Core Principles VI. Minimal Code (1.2.0)
- Core Principles VII. Single Code Path (1.3.0)
- Core Principles VIII. Fail Fast (1.4.0)

Removed sections: N/A

Templates requiring updates:
- .specify/templates/plan-template.md: Add Dogfooding to Constitution Check table [DONE]
- .specify/templates/plan-template.md: Add Minimal Code to Constitution Check table
- .specify/templates/plan-template.md: Add Single Code Path to Constitution Check table
- .specify/templates/plan-template.md: Add Fail Fast to Constitution Check table

Follow-up TODOs: None
-->
Expand Down Expand Up @@ -160,6 +160,21 @@ parse → validate → execute

**Rationale**: We don't want command-specific bugs. We don't want to maintain multiple code paths. Keep it simple. Keep it DRY. No one wants wet code.

### VIII. Fail Fast

Code MUST fail immediately and loudly when something is wrong. Silent failures and deferred errors are bugs.

- Use assertions liberally. If a condition should never happen, assert it.
- Validate inputs at the boundary. Reject garbage immediately, don't propagate it.
- Panic on impossible states rather than returning meaningless defaults.
- Error messages MUST be specific: what failed, why, and where.
- NO defensive coding that papers over bugs. If caller passes nil, panic. Don't check and silently return.
- NO "graceful degradation" that hides broken behavior. If it's broken, STOP.
- Prefer hard crashes over corrupted state. A crash is debuggable. Corrupted data is a nightmare.
- Tests MUST assert behavior, not just "run without error". A test that doesn't assert is not a test.

**Rationale**: The earlier you find a bug, the cheaper it is to fix. Assertions and hard failures surface bugs at development time, not in production. Whimsy code that "handles" errors by ignoring them creates debugging nightmares. Fail hard, fail fast, fix it now.

## Quality Standards

### Testing Requirements
Expand Down Expand Up @@ -230,4 +245,4 @@ All contributions MUST comply with these principles.
- Complexity MUST be justified in PR descriptions
- Principle violations require explicit exemption with documented rationale

**Version**: 1.3.1 | **Ratified**: 2025-10-14 | **Last Amended**: 2026-01-03
**Version**: 1.4.0 | **Ratified**: 2025-10-14 | **Last Amended**: 2026-01-04
8 changes: 7 additions & 1 deletion cli/scripts/gendocs.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,17 @@ import (
)

func main() {
outputDir := "./web/app/_docs"
outputDir := "../apps/web/app/_docs"
if len(os.Args) > 1 {
outputDir = os.Args[1]
}

// Verify the parent path exists (apps/web/app) - fail fast if structure is wrong
parentDir := strings.TrimSuffix(outputDir, "/_docs")
if _, err := os.Stat(parentDir); os.IsNotExist(err) {
log.Fatalf("web app not found at %s - did the directory structure change?", parentDir)
}

if err := os.MkdirAll(outputDir, 0755); err != nil {
log.Fatalf("failed to create output dir: %v", err)
}
Expand Down
Loading