1+ #! /usr/bin/env bash
2+
3+ set -e
4+
5+ JSON_MODE=false
6+ ARGS=()
7+
8+ VALIDATE_MODE=false
9+
10+ for arg in " $@ " ; do
11+ case " $arg " in
12+ --json)
13+ JSON_MODE=true
14+ ;;
15+ --validate)
16+ VALIDATE_MODE=true
17+ ;;
18+ --help|-h)
19+ echo " Usage: $0 [--json] [--validate]"
20+ echo " --json Output results in JSON format"
21+ echo " --validate Validate existing constitution against team inheritance"
22+ echo " --help Show this help message"
23+ exit 0
24+ ;;
25+ * )
26+ ARGS+=(" $arg " )
27+ ;;
28+ esac
29+ done
30+
31+ # Get script directory and load common functions
32+ SCRIPT_DIR=" $( cd " $( dirname " ${BASH_SOURCE[0]} " ) " && pwd) "
33+ source " $SCRIPT_DIR /common.sh"
34+
35+ # Get all paths and variables from common functions
36+ eval $( get_feature_paths)
37+
38+ # Ensure the .specify/memory directory exists
39+ mkdir -p " $REPO_ROOT /.specify/memory"
40+
41+ CONSTITUTION_FILE=" $REPO_ROOT /.specify/memory/constitution.md"
42+
43+ # Function to load team constitution
44+ load_team_constitution () {
45+ local team_constitution=" "
46+
47+ # Try to find team constitution in team directives
48+ if [[ -n " $TEAM_DIRECTIVES " && -d " $TEAM_DIRECTIVES " ]]; then
49+ # Look for constitution.md in team directives
50+ local team_const_file=" $TEAM_DIRECTIVES /constitution.md"
51+ if [[ -f " $team_const_file " ]]; then
52+ team_constitution=$( cat " $team_const_file " )
53+ else
54+ # Look in context_modules subdirectory
55+ team_const_file=" $TEAM_DIRECTIVES /context_modules/constitution.md"
56+ if [[ -f " $team_const_file " ]]; then
57+ team_constitution=$( cat " $team_const_file " )
58+ fi
59+ fi
60+ fi
61+
62+ # If no team constitution found, use default template
63+ if [[ -z " $team_constitution " ]]; then
64+ team_constitution=" # Project Constitution
65+
66+ ## Core Principles
67+
68+ ### Principle 1: Quality First
69+ All code must meet quality standards and include appropriate testing.
70+
71+ ### Principle 2: Documentation Required
72+ Clear documentation must accompany all significant changes.
73+
74+ ### Principle 3: Security by Default
75+ Security considerations must be addressed for all features.
76+
77+ ## Governance
78+
79+ **Version**: 1.0.0 | **Ratified**: $( date +%Y-%m-%d) | **Last Amended**: $( date +%Y-%m-%d)
80+
81+ *This constitution was auto-generated from team defaults. Customize as needed for your project.*"
82+ fi
83+
84+ echo " $team_constitution "
85+ }
86+
87+ # Function to enhance constitution with project context
88+ enhance_constitution () {
89+ local base_constitution=" $1 "
90+ local project_name=" "
91+
92+ # Try to extract project name from git or directory
93+ if [[ -n " $CURRENT_BRANCH " && " $CURRENT_BRANCH " != " main" ]]; then
94+ project_name=" $CURRENT_BRANCH "
95+ else
96+ project_name=$( basename " $REPO_ROOT " )
97+ fi
98+
99+ # Add project-specific header if not present
100+ if ! echo " $base_constitution " | grep -q " ^# $project_name Constitution" ; then
101+ base_constitution=" # $project_name Constitution
102+
103+ *Inherited from team constitution on $( date +%Y-%m-%d) *
104+
105+ $base_constitution "
106+ fi
107+
108+ echo " $base_constitution "
109+ }
110+
111+ # Function to validate inheritance integrity
112+ validate_inheritance () {
113+ local team_constitution=" $1 "
114+ local project_constitution=" $2 "
115+
116+ # Extract core principles from team constitution
117+ local team_principles=" "
118+ if echo " $team_constitution " | grep -q " ^[0-9]\+\. \*\*.*\*\*" ; then
119+ # Numbered list format
120+ team_principles=$( echo " $team_constitution " | grep " ^[0-9]\+\. \*\*.*\*\*" | sed ' s/^[0-9]\+\. \*\{2\}\(.*\)\*\{2\}.*/\1/' )
121+ fi
122+
123+ # Check if project constitution contains team principles
124+ local missing_principles=" "
125+ for principle in $team_principles ; do
126+ if ! echo " $project_constitution " | grep -qi " $principle " ; then
127+ missing_principles=" $missing_principles$principle , "
128+ fi
129+ done
130+
131+ if [[ -n " $missing_principles " ]]; then
132+ echo " WARNING: Project constitution may be missing some team principles: ${missing_principles% , } "
133+ echo " Consider ensuring all team principles are represented in your project constitution."
134+ else
135+ echo " ✓ Inheritance validation passed - all team principles detected in project constitution"
136+ fi
137+ }
138+
139+ # Function to check for team constitution updates
140+ check_team_updates () {
141+ local team_constitution=" $1 "
142+ local project_constitution=" $2 "
143+
144+ # Check if project constitution has inheritance marker
145+ if echo " $project_constitution " | grep -q " Inherited from team constitution" ; then
146+ local inheritance_date=" "
147+ inheritance_date=$( echo " $project_constitution " | grep " Inherited from team constitution" | sed ' s/.*on \([0-9-]\+\).*/\1/' )
148+
149+ if [[ -n " $inheritance_date " ]]; then
150+ # Get team constitution file modification date
151+ local team_file=" "
152+ if [[ -n " $TEAM_DIRECTIVES " && -d " $TEAM_DIRECTIVES " ]]; then
153+ if [[ -f " $TEAM_DIRECTIVES /constitution.md" ]]; then
154+ team_file=" $TEAM_DIRECTIVES /constitution.md"
155+ elif [[ -f " $TEAM_DIRECTIVES /context_modules/constitution.md" ]]; then
156+ team_file=" $TEAM_DIRECTIVES /context_modules/constitution.md"
157+ fi
158+ fi
159+
160+ if [[ -n " $team_file " ]]; then
161+ local team_mod_date=" "
162+ team_mod_date=$( stat -c %Y " $team_file " 2> /dev/null)
163+
164+ local inheritance_timestamp=" "
165+ inheritance_timestamp=$( date -d " $inheritance_date " +%s 2> /dev/null)
166+
167+ if [[ -n " $team_mod_date " && -n " $inheritance_timestamp " && " $team_mod_date " -gt " $inheritance_timestamp " ]]; then
168+ echo " NOTICE: Team constitution has been updated since project constitution was created."
169+ echo " Consider reviewing the team constitution for any changes that should be reflected in your project."
170+ echo " Team constitution: $team_file "
171+ fi
172+ fi
173+ fi
174+ fi
175+ }
176+
177+ # Validation-only mode
178+ if $VALIDATE_MODE ; then
179+ if [[ ! -f " $CONSTITUTION_FILE " ]]; then
180+ echo " ERROR: No constitution file found at $CONSTITUTION_FILE "
181+ echo " Run without --validate to create the constitution first."
182+ exit 1
183+ fi
184+
185+ # Load constitutions for validation
186+ TEAM_CONSTITUTION=$( load_team_constitution)
187+ PROJECT_CONSTITUTION=$( cat " $CONSTITUTION_FILE " )
188+
189+ if $JSON_MODE ; then
190+ # Basic validation result
191+ printf ' {"status":"validated","file":"%s","team_directives":"%s"}\n' " $CONSTITUTION_FILE " " $TEAM_DIRECTIVES "
192+ else
193+ echo " Validating constitution at: $CONSTITUTION_FILE "
194+ echo " Team directives source: $TEAM_DIRECTIVES "
195+ echo " "
196+ validate_inheritance " $TEAM_CONSTITUTION " " $PROJECT_CONSTITUTION "
197+ echo " "
198+ check_team_updates " $TEAM_CONSTITUTION " " $PROJECT_CONSTITUTION "
199+ fi
200+ exit 0
201+ fi
202+
203+ # Main logic
204+ if [[ -f " $CONSTITUTION_FILE " ]]; then
205+ echo " Constitution file already exists at $CONSTITUTION_FILE "
206+ echo " Use git to modify it directly, or remove it to recreate from team directives."
207+
208+ # Load team constitution for comparison
209+ TEAM_CONSTITUTION=$( load_team_constitution)
210+ EXISTING_CONSTITUTION=$( cat " $CONSTITUTION_FILE " )
211+
212+ # Check for team constitution updates
213+ if ! $JSON_MODE ; then
214+ check_team_updates " $TEAM_CONSTITUTION " " $EXISTING_CONSTITUTION "
215+ echo " "
216+ fi
217+
218+ if $JSON_MODE ; then
219+ printf ' {"status":"exists","file":"%s"}\n' " $CONSTITUTION_FILE "
220+ fi
221+ exit 0
222+ fi
223+
224+ # Load team constitution
225+ TEAM_CONSTITUTION=$( load_team_constitution)
226+
227+ # Enhance with project context
228+ PROJECT_CONSTITUTION=$( enhance_constitution " $TEAM_CONSTITUTION " )
229+
230+ # Validate inheritance integrity
231+ if ! $JSON_MODE ; then
232+ validate_inheritance " $TEAM_CONSTITUTION " " $PROJECT_CONSTITUTION "
233+ echo " "
234+ fi
235+
236+ # Write to file
237+ echo " $PROJECT_CONSTITUTION " > " $CONSTITUTION_FILE "
238+
239+ # Output results
240+ if $JSON_MODE ; then
241+ printf ' {"status":"created","file":"%s","team_directives":"%s"}\n' " $CONSTITUTION_FILE " " $TEAM_DIRECTIVES "
242+ else
243+ echo " Constitution created at: $CONSTITUTION_FILE "
244+ echo " Team directives source: $TEAM_DIRECTIVES "
245+ echo " "
246+ echo " Next steps:"
247+ echo " 1. Review and customize the constitution for your project needs"
248+ echo " 2. Commit the constitution: git add .specify/memory/constitution.md && git commit -m 'docs: initialize project constitution'"
249+ echo " 3. The constitution will be used by planning and implementation commands"
250+ fi
0 commit comments