ai-core-framework 0.1.0

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 (103) hide show
  1. package/.claude-plugin/plugin.json +21 -0
  2. package/.codex-plugin/plugin.json +35 -0
  3. package/.cursor-plugin/plugin.json +22 -0
  4. package/README.md +173 -0
  5. package/bin/ai-core-framework.js +110 -0
  6. package/core/README.md +162 -0
  7. package/core/agents/README.md +32 -0
  8. package/core/agents/business-analyst.md +269 -0
  9. package/core/agents/developer.md +375 -0
  10. package/core/agents/qa-tester.md +477 -0
  11. package/core/agents/scrum-master.md +136 -0
  12. package/core/agents/tech-lead.md +345 -0
  13. package/core/config/backlog.schema.json +38 -0
  14. package/core/config/docs-policy.default.json +37 -0
  15. package/core/config/release.schema.json +120 -0
  16. package/core/config/ticket.schema.json +253 -0
  17. package/core/rules/00-global-rules.md +373 -0
  18. package/core/rules/01-git-workflow.md +388 -0
  19. package/core/rules/02-code-quality.md +77 -0
  20. package/core/rules/03-security.md +78 -0
  21. package/core/rules/04-documentation.md +72 -0
  22. package/core/rules/05-testing-mandatory.md +374 -0
  23. package/core/rules/06-approval-gates.md +388 -0
  24. package/core/rules/07-definition-of-ready.md +112 -0
  25. package/core/rules/08-definition-of-done.md +149 -0
  26. package/core/scripts/ai-core.sh +456 -0
  27. package/core/scripts/generate-views.sh +210 -0
  28. package/core/scripts/install-codex-prompts.sh +127 -0
  29. package/core/scripts/log-user-request.sh +113 -0
  30. package/core/scripts/setup-project.sh +183 -0
  31. package/core/scripts/sync-platforms.sh +322 -0
  32. package/core/scripts/validate-audit-log.sh +73 -0
  33. package/core/scripts/validate-docs.sh +365 -0
  34. package/core/scripts/validate-permissions.sh +132 -0
  35. package/core/scripts/validate-state.sh +611 -0
  36. package/core/scripts/workflow.sh +513 -0
  37. package/core/skills/README.md +21 -0
  38. package/core/skills/ai-core-commands/SKILL.md +86 -0
  39. package/core/skills/brainstorming/SKILL.md +40 -0
  40. package/core/skills/development-implement-task/SKILL.md +308 -0
  41. package/core/skills/executing-ticket/SKILL.md +28 -0
  42. package/core/skills/git-branch-status/SKILL.md +56 -0
  43. package/core/skills/git-cleanup-branches/SKILL.md +57 -0
  44. package/core/skills/git-scan-untracked/SKILL.md +50 -0
  45. package/core/skills/meta-generate-views/SKILL.md +54 -0
  46. package/core/skills/meta-request-log/SKILL.md +61 -0
  47. package/core/skills/meta-sprint-report/SKILL.md +59 -0
  48. package/core/skills/meta-sync-platforms/SKILL.md +53 -0
  49. package/core/skills/meta-ticket-health/SKILL.md +61 -0
  50. package/core/skills/meta-validate-audit-log/SKILL.md +42 -0
  51. package/core/skills/meta-validate-docs/SKILL.md +58 -0
  52. package/core/skills/meta-validate-permissions/SKILL.md +53 -0
  53. package/core/skills/meta-validate-state/SKILL.md +58 -0
  54. package/core/skills/planning-analyze-requirements/SKILL.md +471 -0
  55. package/core/skills/planning-backlog-status/SKILL.md +57 -0
  56. package/core/skills/planning-document-existing-requirements/SKILL.md +246 -0
  57. package/core/skills/planning-estimate-task/SKILL.md +60 -0
  58. package/core/skills/planning-groom-ticket/SKILL.md +442 -0
  59. package/core/skills/planning-mark-ready/SKILL.md +111 -0
  60. package/core/skills/planning-plan-refactor/SKILL.md +66 -0
  61. package/core/skills/planning-plan-sprint/SKILL.md +112 -0
  62. package/core/skills/planning-prioritize-backlog/SKILL.md +62 -0
  63. package/core/skills/planning-write-plan/SKILL.md +68 -0
  64. package/core/skills/project-detect-stack/SKILL.md +71 -0
  65. package/core/skills/project-discover-codebase/SKILL.md +74 -0
  66. package/core/skills/project-setup-project/SKILL.md +113 -0
  67. package/core/skills/qa-bug-status/SKILL.md +52 -0
  68. package/core/skills/qa-report-bug/SKILL.md +518 -0
  69. package/core/skills/qa-smoke-test/SKILL.md +387 -0
  70. package/core/skills/qa-triage-bug/SKILL.md +62 -0
  71. package/core/skills/qa-verify-fix/SKILL.md +446 -0
  72. package/core/skills/release-hotfix/SKILL.md +117 -0
  73. package/core/skills/release-release/SKILL.md +123 -0
  74. package/core/skills/release-rollback/SKILL.md +62 -0
  75. package/core/skills/review-create-pr/SKILL.md +418 -0
  76. package/core/skills/review-merge-pr/SKILL.md +425 -0
  77. package/core/skills/review-techlead-review/SKILL.md +547 -0
  78. package/core/skills/using-ai-core/SKILL.md +72 -0
  79. package/core/skills/verification-before-done/SKILL.md +35 -0
  80. package/core/skills/writing-implementation-plan/SKILL.md +45 -0
  81. package/core/templates/ci/ai-core-governance.yml +112 -0
  82. package/core/templates/ci/node-pnpm.yml +35 -0
  83. package/core/templates/pm/retrospective-template.md +47 -0
  84. package/core/templates/pm/sprint-plan-template.md +45 -0
  85. package/core/templates/pr/pull-request-template.md +247 -0
  86. package/core/templates/project/CODEOWNERS +11 -0
  87. package/core/templates/project/docs-policy.json +3 -0
  88. package/core/templates/project/project-config.yaml +137 -0
  89. package/core/templates/project/project-structure.yaml +76 -0
  90. package/core/templates/qa/bug-report-template.md +371 -0
  91. package/core/templates/qa/test-plan-template.md +57 -0
  92. package/core/templates/release/release-record-template.json +67 -0
  93. package/core/templates/requirements/PRD-template.md +58 -0
  94. package/core/templates/requirements/user-story-template.md +381 -0
  95. package/core/templates/technical/ADR-template.md +46 -0
  96. package/core/templates/technical/refactor-plan-template.md +84 -0
  97. package/core/templates/technical/tech-design-template.md +71 -0
  98. package/core/workflows/bug-lifecycle.md +56 -0
  99. package/core/workflows/feature-lifecycle.md +347 -0
  100. package/core/workflows/hotfix-lifecycle.md +65 -0
  101. package/core/workflows/sprint-lifecycle.md +56 -0
  102. package/lib/install-codex.js +85 -0
  103. package/package.json +36 -0
@@ -0,0 +1,513 @@
1
+ #!/usr/bin/env bash
2
+ # core/scripts/workflow.sh
3
+ #
4
+ # Executable handlers for AI Core state workflow commands.
5
+
6
+ set -euo pipefail
7
+
8
+ COMMAND="${1:-}"
9
+ shift || true
10
+
11
+ RED='\033[0;31m'
12
+ GREEN='\033[0;32m'
13
+ BLUE='\033[0;34m'
14
+ NC='\033[0m'
15
+
16
+ log_info() { echo -e "${BLUE}i${NC} $1"; }
17
+ log_pass() { echo -e "${GREEN}+${NC} $1"; }
18
+ log_fail() { echo -e "${RED}x${NC} $1"; }
19
+
20
+ require_jq() {
21
+ if ! command -v jq >/dev/null 2>&1; then
22
+ log_fail "jq not installed. Install with: brew install jq"
23
+ exit 2
24
+ fi
25
+ }
26
+
27
+ now_utc() {
28
+ date -u +%Y-%m-%dT%H:%M:%SZ
29
+ }
30
+
31
+ agent_name() {
32
+ local agent="${AI_AGENT:-unknown-agent}"
33
+ if [[ "$agent" == *-agent ]]; then
34
+ printf '%s' "$agent"
35
+ else
36
+ printf '%s-agent' "$agent"
37
+ fi
38
+ }
39
+
40
+ ticket_file() {
41
+ printf 'project/tickets/%s.json' "$1"
42
+ }
43
+
44
+ slugify() {
45
+ printf '%s' "$1" |
46
+ tr '[:upper:]' '[:lower:]' |
47
+ sed -E 's/[^a-z0-9]+/-/g; s/^-+//; s/-+$//; s/-+/-/g' |
48
+ cut -c1-60
49
+ }
50
+
51
+ next_ticket_id() {
52
+ local max_id
53
+ max_id=$(find project/tickets -name 'TICKET-*.json' -type f 2>/dev/null |
54
+ sed -E 's/.*TICKET-([0-9]+)\.json/\1/' |
55
+ sort -n |
56
+ tail -1)
57
+ if [ -z "$max_id" ]; then
58
+ printf 'TICKET-001'
59
+ else
60
+ printf 'TICKET-%03d' "$((10#$max_id + 1))"
61
+ fi
62
+ }
63
+
64
+ write_json() {
65
+ local file="$1"
66
+ local tmp
67
+ tmp=$(mktemp)
68
+ cat > "$tmp"
69
+ mv "$tmp" "$file"
70
+ }
71
+
72
+ hash_value() {
73
+ local value="$1"
74
+ if command -v sha256sum >/dev/null 2>&1; then
75
+ printf '%s' "$value" | sha256sum | awk '{print $1}'
76
+ else
77
+ printf '%s' "$value" | shasum -a 256 | awk '{print $1}'
78
+ fi
79
+ }
80
+
81
+ last_audit_hash() {
82
+ local audit_file="project/audit-log.jsonl"
83
+ if [ ! -s "$audit_file" ]; then
84
+ printf ''
85
+ return 0
86
+ fi
87
+ tail -1 "$audit_file" | jq -r '.hash // empty'
88
+ }
89
+
90
+ append_audit() {
91
+ local command="$1"
92
+ local ticket_id="$2"
93
+ local from_state="$3"
94
+ local to_state="$4"
95
+ local reason="$5"
96
+
97
+ mkdir -p project
98
+ local audit_file="project/audit-log.jsonl"
99
+ local at by prev payload hash
100
+ at=$(now_utc)
101
+ by=$(agent_name)
102
+ prev=$(last_audit_hash)
103
+ payload=$(jq -cn \
104
+ --arg at "$at" \
105
+ --arg by "$by" \
106
+ --arg command "$command" \
107
+ --arg ticket_id "$ticket_id" \
108
+ --arg from_state "$from_state" \
109
+ --arg to_state "$to_state" \
110
+ --arg reason "$reason" \
111
+ --arg prev_hash "$prev" \
112
+ '{at:$at, by_agent:$by, command:$command, ticket_id:$ticket_id, from_state:$from_state, to_state:$to_state, reason:$reason, prev_hash:$prev_hash}')
113
+ hash=$(hash_value "$payload")
114
+ jq -cn --argjson payload "$payload" --arg hash "$hash" '$payload + {hash:$hash}' >> "$audit_file"
115
+ }
116
+
117
+ transition_ticket() {
118
+ local ticket_id="$1"
119
+ local from_state="$2"
120
+ local to_state="$3"
121
+ local command="$4"
122
+ local reason="$5"
123
+ local file
124
+ file=$(ticket_file "$ticket_id")
125
+
126
+ if [ ! -f "$file" ]; then
127
+ log_fail "Ticket not found: $ticket_id"
128
+ exit 1
129
+ fi
130
+
131
+ local status
132
+ status=$(jq -r '.status' "$file")
133
+ if [ "$status" != "$from_state" ]; then
134
+ log_fail "$ticket_id status must be $from_state, got $status"
135
+ exit 1
136
+ fi
137
+
138
+ local at by
139
+ at=$(now_utc)
140
+ by=$(agent_name)
141
+
142
+ jq \
143
+ --arg status "$to_state" \
144
+ --arg at "$at" \
145
+ --arg by "$by" \
146
+ --arg command "$command" \
147
+ --arg from_state "$from_state" \
148
+ --arg to_state "$to_state" \
149
+ --arg reason "$reason" \
150
+ '.status = $status
151
+ | .updated_at = $at
152
+ | .state_history += [{
153
+ from_state: $from_state,
154
+ to_state: $to_state,
155
+ at: $at,
156
+ by_agent: $by,
157
+ by_command: $command,
158
+ reason: $reason
159
+ }]' "$file" | write_json "$file"
160
+
161
+ append_audit "$command" "$ticket_id" "$from_state" "$to_state" "$reason"
162
+ bash core/scripts/validate-state.sh "$ticket_id"
163
+ bash core/scripts/validate-permissions.sh
164
+ log_pass "$ticket_id transitioned $from_state -> $to_state"
165
+ }
166
+
167
+ require_ticket_field() {
168
+ local ticket_id="$1"
169
+ local query="$2"
170
+ local message="$3"
171
+ if ! jq -e "$query" "$(ticket_file "$ticket_id")" >/dev/null 2>&1; then
172
+ log_fail "$ticket_id: $message"
173
+ exit 1
174
+ fi
175
+ }
176
+
177
+ cmd_analyze_requirements() {
178
+ local requirement="${*:-}"
179
+ if [ ${#requirement} -lt 10 ]; then
180
+ log_fail "Requirement text must be at least 10 characters"
181
+ exit 1
182
+ fi
183
+
184
+ mkdir -p project/tickets docs/project/specs
185
+ local ticket_id file at by slug spec_path
186
+ ticket_id=$(next_ticket_id)
187
+ file=$(ticket_file "$ticket_id")
188
+ at=$(now_utc)
189
+ by=$(agent_name)
190
+ slug=$(slugify "$requirement")
191
+ [ -n "$slug" ] || slug="requirement"
192
+ spec_path="docs/project/specs/${ticket_id}-${slug}.md"
193
+
194
+ cat > "$spec_path" <<EOF
195
+ # ${ticket_id}: ${requirement:0:120}
196
+
197
+ ## Goal
198
+
199
+ ${requirement}
200
+
201
+ ## Background
202
+
203
+ Created by /analyze-requirements from stakeholder input.
204
+
205
+ ## Users And Stakeholders
206
+
207
+ - Primary user: stakeholder
208
+ - Owner agent: $by
209
+
210
+ ## In Scope
211
+
212
+ - Convert the requirement into a groomable ticket.
213
+ - Validate expected behavior through acceptance criteria.
214
+
215
+ ## Out Of Scope
216
+
217
+ - Technical implementation details.
218
+ - Story point estimation.
219
+
220
+ ## Acceptance Criteria
221
+
222
+ 1. Happy path: valid preconditions produce the expected outcome.
223
+ 2. Edge case: boundary input or uncommon state is handled predictably.
224
+ 3. Error case: invalid input or unavailable dependency produces a safe error and no data corruption.
225
+
226
+ ## Risks And Assumptions
227
+
228
+ - Requirement may need refinement during grooming.
229
+ - Technical risks are owned by /groom-ticket and /write-plan.
230
+
231
+ ## Next Command
232
+
233
+ \`/groom-ticket ${ticket_id} <story_points>\`
234
+ EOF
235
+
236
+ jq -n \
237
+ --arg id "$ticket_id" \
238
+ --arg title "${requirement:0:120}" \
239
+ --arg req "$requirement" \
240
+ --arg at "$at" \
241
+ --arg by "$by" \
242
+ --arg spec_path "$spec_path" \
243
+ '{
244
+ id: $id,
245
+ title: $title,
246
+ type: "feature",
247
+ status: "DRAFT",
248
+ priority: "SHOULD",
249
+ user_story: {
250
+ as_a: "stakeholder",
251
+ i_want: $req,
252
+ so_that: "business value can be validated"
253
+ },
254
+ acceptance_criteria: [
255
+ {scenario:"Happy path", given:"valid preconditions", when:"the user performs the requested action", then:"the expected outcome is achieved"},
256
+ {scenario:"Edge case", given:"boundary input or uncommon state", when:"the action is attempted", then:"the system handles it predictably"},
257
+ {scenario:"Error case", given:"invalid input or unavailable dependency", when:"the action is attempted", then:"the user receives a safe error and no data is corrupted"}
258
+ ],
259
+ created_at: $at,
260
+ created_by: $by,
261
+ updated_at: $at,
262
+ spec_path: $spec_path,
263
+ state_history: [{
264
+ from_state: null,
265
+ to_state: "DRAFT",
266
+ at: $at,
267
+ by_agent: $by,
268
+ by_command: "/analyze-requirements",
269
+ reason: "Created from executable requirement intake"
270
+ }],
271
+ comments: [{
272
+ author: $by,
273
+ at: $at,
274
+ text: ("Source requirement: " + $req)
275
+ }],
276
+ labels: ["needs-grooming"]
277
+ }' > "$file"
278
+
279
+ append_audit "/analyze-requirements" "$ticket_id" "null" "DRAFT" "Created from executable requirement intake"
280
+ bash core/scripts/validate-state.sh "$ticket_id"
281
+ log_pass "Created $ticket_id"
282
+ log_pass "Created $spec_path"
283
+ }
284
+
285
+ cmd_groom_ticket() {
286
+ local ticket_id="${1:-}"
287
+ local points="${2:-}"
288
+ [ -n "$ticket_id" ] || { log_fail "Usage: /groom-ticket TICKET-XXX [points]"; exit 2; }
289
+
290
+ if [ -n "$points" ]; then
291
+ local file at by
292
+ file=$(ticket_file "$ticket_id")
293
+ at=$(now_utc)
294
+ by=$(agent_name)
295
+ jq --argjson points "$points" --arg by "$by" --arg at "$at" \
296
+ '.estimate = {story_points:$points, estimated_by:$by, estimated_at:$at}
297
+ | .technical_approach = (.technical_approach // "Executable grooming recorded. Add detailed approach before implementation.")
298
+ | .risks = (.risks // [{description:"Implementation risk requires Tech Lead review", probability:"MEDIUM", impact:"MEDIUM", mitigation:"Review before sprint planning"}])' "$file" | write_json "$file"
299
+ fi
300
+
301
+ require_ticket_field "$ticket_id" '.user_story' "missing user_story"
302
+ require_ticket_field "$ticket_id" '.acceptance_criteria | length >= 3' "requires at least 3 acceptance criteria"
303
+ require_ticket_field "$ticket_id" '.estimate.story_points' "missing estimate.story_points; pass points or add estimate"
304
+ transition_ticket "$ticket_id" "DRAFT" "GROOMED" "/groom-ticket" "Executable grooming gate passed"
305
+ }
306
+
307
+ cmd_mark_ready() {
308
+ local ticket_id="${1:-}"
309
+ [ -n "$ticket_id" ] || { log_fail "Usage: /mark-ready TICKET-XXX"; exit 2; }
310
+ require_ticket_field "$ticket_id" '.estimate.story_points' "missing estimate"
311
+ require_ticket_field "$ticket_id" '.acceptance_criteria | length >= 3' "requires at least 3 acceptance criteria"
312
+ transition_ticket "$ticket_id" "GROOMED" "READY" "/mark-ready" "Definition of Ready gate passed"
313
+ }
314
+
315
+ cmd_write_plan() {
316
+ local ticket_id="${1:-}"
317
+ [ -n "$ticket_id" ] || { log_fail "Usage: /write-plan TICKET-XXX"; exit 2; }
318
+
319
+ local file status title slug plan_path spec_path at by
320
+ file=$(ticket_file "$ticket_id")
321
+ [ -f "$file" ] || { log_fail "Ticket not found: $ticket_id"; exit 1; }
322
+ status=$(jq -r '.status // empty' "$file")
323
+ case "$status" in
324
+ GROOMED|READY) ;;
325
+ *) log_fail "$ticket_id status must be GROOMED or READY before /write-plan, got $status"; exit 1 ;;
326
+ esac
327
+
328
+ mkdir -p docs/project/plans
329
+ title=$(jq -r '.title // .id' "$file")
330
+ slug=$(slugify "$title")
331
+ [ -n "$slug" ] || slug="implementation"
332
+ plan_path="docs/project/plans/${ticket_id}-${slug}-plan.md"
333
+ spec_path=$(jq -r '.spec_path // empty' "$file")
334
+ at=$(now_utc)
335
+ by=$(agent_name)
336
+
337
+ cat > "$plan_path" <<EOF
338
+ # ${ticket_id}: ${title} Implementation Plan
339
+
340
+ **Ticket:** \`${ticket_id}\`
341
+ **Status at planning:** \`${status}\`
342
+ **Spec:** ${spec_path:-Not linked}
343
+ **Created by:** ${by}
344
+ **Created at:** ${at}
345
+
346
+ ## Goal
347
+
348
+ Implement the ticket scope while preserving the approved acceptance criteria and documentation obligations.
349
+
350
+ ## Current Context
351
+
352
+ - Read \`project/tickets/${ticket_id}.json\`.
353
+ - Read the linked spec if present.
354
+ - Inspect affected code before editing.
355
+
356
+ ## Affected Files
357
+
358
+ - To be confirmed by the developer before implementation.
359
+ - Add exact paths here if codebase discovery identifies them.
360
+
361
+ ## Tasks
362
+
363
+ - [ ] Confirm ticket scope and acceptance criteria.
364
+ - [ ] Identify exact production files and test files.
365
+ - [ ] Write or update failing tests for the happy path.
366
+ - [ ] Write or update failing tests for edge/error cases.
367
+ - [ ] Implement the smallest code change that satisfies the tests.
368
+ - [ ] Run targeted tests and record output.
369
+ - [ ] Update docs required by the ticket metadata.
370
+ - [ ] Run validation gates: state, permissions, docs, audit log.
371
+
372
+ ## Test Strategy
373
+
374
+ - Unit tests for deterministic logic.
375
+ - Integration tests for changed boundaries.
376
+ - Manual or smoke-test evidence before DONE.
377
+
378
+ ## Documentation Updates
379
+
380
+ - Update \`documentation.paths\` in the ticket when docs are required.
381
+ - Add ADR or runbook links if architecture, migration, or operations behavior changes.
382
+
383
+ ## Verification Commands
384
+
385
+ \`\`\`text
386
+ /validate-state
387
+ /validate-permissions
388
+ /validate-docs
389
+ \`\`\`
390
+
391
+ ## Rollback Notes
392
+
393
+ Rollback should revert the implementation commit or disable the changed behavior behind the safest available control. Add a more specific rollback path before release if this touches data, auth, billing, deployment, or migrations.
394
+
395
+ ## Next Command
396
+
397
+ \`/implement-task ${ticket_id}\`
398
+ EOF
399
+
400
+ jq --arg path "$plan_path" --arg at "$at" --arg by "$by" \
401
+ '.implementation_plan_path = $path
402
+ | .updated_at = $at
403
+ | .comments = ((.comments // []) + [{
404
+ author: $by,
405
+ at: $at,
406
+ text: ("Implementation plan created: " + $path)
407
+ }])' "$file" | write_json "$file"
408
+
409
+ append_audit "/write-plan" "$ticket_id" "$status" "$status" "Implementation plan created"
410
+ bash core/scripts/validate-state.sh "$ticket_id"
411
+ bash core/scripts/validate-permissions.sh
412
+ log_pass "Created $plan_path"
413
+ log_pass "Linked plan from $file"
414
+ }
415
+
416
+ cmd_implement_task() {
417
+ local ticket_id="${1:-}"
418
+ [ -n "$ticket_id" ] || { log_fail "Usage: /implement-task TICKET-XXX"; exit 2; }
419
+ if ! jq -e '.implementation_plan_path // empty' "$(ticket_file "$ticket_id")" >/dev/null 2>&1; then
420
+ log_info "$ticket_id has no implementation_plan_path. Recommended first: /write-plan $ticket_id"
421
+ fi
422
+ transition_ticket "$ticket_id" "READY" "IN_PROGRESS" "/implement-task" "Implementation started"
423
+ }
424
+
425
+ cmd_create_pr() {
426
+ local ticket_id="${1:-}"
427
+ local pr_url="${2:-}"
428
+ [ -n "$ticket_id" ] || { log_fail "Usage: /create-pr TICKET-XXX [pr_url]"; exit 2; }
429
+ if [ "$(jq -r '.status' "$(ticket_file "$ticket_id")")" != "IN_PROGRESS" ]; then
430
+ log_fail "$ticket_id status must be IN_PROGRESS before PR metadata is written"
431
+ exit 1
432
+ fi
433
+ if [ -n "$pr_url" ]; then
434
+ jq --arg pr_url "$pr_url" '.pr_url = $pr_url' "$(ticket_file "$ticket_id")" | write_json "$(ticket_file "$ticket_id")"
435
+ fi
436
+ require_ticket_field "$ticket_id" '.pr_url // empty' "missing pr_url; pass PR URL"
437
+ transition_ticket "$ticket_id" "IN_PROGRESS" "IN_REVIEW" "/create-pr" "PR created and linked"
438
+ }
439
+
440
+ cmd_merge_pr() {
441
+ local ticket_id="${1:-}"
442
+ [ -n "$ticket_id" ] || { log_fail "Usage: /merge-pr TICKET-XXX"; exit 2; }
443
+ require_ticket_field "$ticket_id" '.pr_url // empty' "missing pr_url"
444
+ transition_ticket "$ticket_id" "IN_REVIEW" "QA" "/merge-pr" "PR merged and ready for QA"
445
+ }
446
+
447
+ cmd_smoke_test() {
448
+ local ticket_id="${1:-}"
449
+ local evidence_path="${2:-}"
450
+ [ -n "$ticket_id" ] || { log_fail "Usage: /smoke-test TICKET-XXX [evidence_path]"; exit 2; }
451
+ if [ "$(jq -r '.status' "$(ticket_file "$ticket_id")")" != "QA" ]; then
452
+ log_fail "$ticket_id status must be QA before QA evidence is written"
453
+ exit 1
454
+ fi
455
+ [ -n "$evidence_path" ] || evidence_path="project/test-runs/${ticket_id}-$(date -u +%Y%m%d%H%M%S).md"
456
+ mkdir -p "$(dirname "$evidence_path")"
457
+ if [ ! -f "$evidence_path" ]; then
458
+ printf '# Smoke Test Evidence: %s\n\nGenerated by executable smoke-test gate at %s.\n' "$ticket_id" "$(now_utc)" > "$evidence_path"
459
+ fi
460
+ local at by
461
+ at=$(now_utc)
462
+ by=$(agent_name)
463
+ jq --arg path "$evidence_path" --arg by "$by" --arg at "$at" \
464
+ '.qa_evidence = {required:true, path:$path, verified_by:$by, verified_at:$at}
465
+ | .dod_checklist = ((.dod_checklist // {}) + {
466
+ code_complete:true,
467
+ tests_passed:true,
468
+ docs_updated:true,
469
+ review_approved:true,
470
+ qa_verified:true,
471
+ release_notes_updated:true,
472
+ security_checked:true
473
+ })
474
+ | .completed_at = $at' "$(ticket_file "$ticket_id")" | write_json "$(ticket_file "$ticket_id")"
475
+ transition_ticket "$ticket_id" "QA" "DONE" "/smoke-test" "Smoke test passed with evidence"
476
+ }
477
+
478
+ cmd_release() {
479
+ local version="${1:-}"
480
+ [ -n "$version" ] || { log_fail "Usage: /release vMAJOR.MINOR.PATCH"; exit 2; }
481
+ mkdir -p project/releases
482
+ local file="project/releases/${version}.json"
483
+ if [ -f "$file" ]; then
484
+ log_fail "Release record already exists: $file"
485
+ exit 1
486
+ fi
487
+ local at by
488
+ at=$(now_utc)
489
+ by=$(agent_name)
490
+ jq --arg version "$version" --arg at "$at" --arg by "$by" \
491
+ '.version = $version
492
+ | .created_at = $at
493
+ | .created_by = $by' core/templates/release/release-record-template.json > "$file"
494
+ log_pass "Created release record $file"
495
+ }
496
+
497
+ main() {
498
+ require_jq
499
+ case "$COMMAND" in
500
+ analyze-requirements) cmd_analyze_requirements "$@" ;;
501
+ groom-ticket) cmd_groom_ticket "$@" ;;
502
+ write-plan) cmd_write_plan "$@" ;;
503
+ mark-ready) cmd_mark_ready "$@" ;;
504
+ implement-task) cmd_implement_task "$@" ;;
505
+ create-pr) cmd_create_pr "$@" ;;
506
+ merge-pr) cmd_merge_pr "$@" ;;
507
+ smoke-test) cmd_smoke_test "$@" ;;
508
+ release) cmd_release "$@" ;;
509
+ *) log_fail "No workflow handler for $COMMAND"; exit 2 ;;
510
+ esac
511
+ }
512
+
513
+ main "$@"
@@ -0,0 +1,21 @@
1
+ # AI Core Skills
2
+
3
+ Skills define chat-first agent behavior. Commands define workflow actions. Scripts implement deterministic checks and state updates.
4
+
5
+ Use skills when the user intent is broader than one command:
6
+
7
+ - `using-ai-core`: session bootstrap and command interpretation
8
+ - `ai-core-commands`: interpret AI Core slash-command text in Codex chat
9
+ - `brainstorming`: requirement discovery before ticket work
10
+ - `writing-implementation-plan`: detailed plan creation before coding
11
+ - `executing-ticket`: implementation discipline for active tickets
12
+ - `verification-before-done`: evidence gate before completion claims
13
+
14
+ Normal user interaction should stay in chat:
15
+
16
+ ```text
17
+ /analyze-requirements "User can reset password"
18
+ /groom-ticket TICKET-001 5
19
+ /write-plan TICKET-001
20
+ next TICKET-001
21
+ ```
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: ai-core-commands
3
+ description: Interpret AI Core slash-command text in Codex. Use when the user types AI Core commands such as /setup-project, /analyze-requirements, /document-existing-requirements, /groom-ticket, /write-plan, /implement-task, /request-log, or asks to run an AI Core workflow command.
4
+ ---
5
+
6
+ # AI Core Commands
7
+
8
+ Codex plugins do not expose `core/commands/*.md` as native slash-command autocomplete. This skill makes AI Core command text executable through normal chat.
9
+
10
+ ## Mandatory Trigger
11
+
12
+ Use this skill when the user message starts with, mentions, or asks to run any AI Core command:
13
+
14
+ ```text
15
+ /setup-project
16
+ /analyze-requirements
17
+ /document-existing-requirements
18
+ /groom-ticket
19
+ /mark-ready
20
+ /write-plan
21
+ /implement-task
22
+ /create-pr
23
+ /techlead-review
24
+ /merge-pr
25
+ /smoke-test
26
+ /verify-fix
27
+ /release
28
+ /request-log
29
+ guide /...
30
+ next TICKET-XXX
31
+ ```
32
+
33
+ ## Required Behavior
34
+
35
+ 1. Log the user request first:
36
+ ```bash
37
+ AI_AGENT=codex bash core/scripts/log-user-request.sh "<user request text>"
38
+ ```
39
+
40
+ 2. Resolve command metadata:
41
+ - Search `core/commands/**/<command-name>.md`.
42
+ - Read the command file.
43
+ - Infer `owner_agent`, `requires_agents`, args, preconditions, postconditions, hard rules, and output format.
44
+
45
+ 3. Load the matching agent file when present:
46
+ - `core/agents/<owner_agent>.md`
47
+
48
+ 4. Execute the command in chat-first mode:
49
+ - Use deterministic scripts only when the command file or workflow requires them.
50
+ - Do not ask the user to run shell wrappers during normal use.
51
+ - Preserve all hard rules from `core/rules/00-global-rules.md`.
52
+
53
+ 5. Report:
54
+ - Command executed
55
+ - Inferred agent
56
+ - Files created or changed
57
+ - Validation result
58
+ - Suggested next AI Core command
59
+
60
+ ## Command Discovery
61
+
62
+ Command files are stored under:
63
+
64
+ ```text
65
+ core/commands/
66
+ ```
67
+
68
+ The command name maps to a Markdown file by removing the leading slash:
69
+
70
+ ```text
71
+ /analyze-requirements -> core/commands/**/analyze-requirements.md
72
+ /request-log -> core/commands/**/request-log.md
73
+ ```
74
+
75
+ If multiple files match the same command name, stop and ask for clarification.
76
+
77
+ If no file matches, say the command is not defined and suggest `/request-log`, `/setup-project`, or checking `core/commands/README.md`.
78
+
79
+ ## Strict Rules
80
+
81
+ - MUST NOT invent command behavior not present in command files.
82
+ - MUST NOT skip required preconditions.
83
+ - MUST NOT silently skip request logging.
84
+ - MUST NOT modify production code unless AI Core ticket rules allow it.
85
+ - MUST distinguish native Codex slash commands from AI Core chat commands. AI Core commands may not appear in `/` autocomplete, but they still MUST be interpreted when typed in chat.
86
+
@@ -0,0 +1,40 @@
1
+ ---
2
+ name: brainstorming
3
+ description: Use before creating or changing product behavior. Converts a rough idea into an approved spec before ticket grooming or implementation.
4
+ ---
5
+
6
+ # Brainstorming
7
+
8
+ Use this before implementation work, feature creation, behavior changes, or large refactors.
9
+
10
+ ## Process
11
+
12
+ 1. Inspect current project context briefly.
13
+ 2. Ask clarifying questions one at a time when the requirement is ambiguous.
14
+ 3. Propose 2-3 approaches with tradeoffs and a recommendation.
15
+ 4. Present a concise design for user approval.
16
+ 5. Save the approved spec to `docs/project/specs/TICKET-XXX-<slug>.md`.
17
+ 6. Link the spec from `project/tickets/TICKET-XXX.json` as `spec_path`.
18
+ 7. Suggest `/groom-ticket TICKET-XXX`.
19
+
20
+ ## Hard Gates
21
+
22
+ - Do not write production code during brainstorming.
23
+ - Do not invent missing business requirements silently.
24
+ - Do not estimate story points. Estimation belongs to `/groom-ticket`.
25
+ - Do not create implementation plans here. Use `/write-plan` after the ticket is groomed or ready.
26
+
27
+ ## Spec Contents
28
+
29
+ Each spec should include:
30
+
31
+ - goal
32
+ - background
33
+ - users and stakeholders
34
+ - in-scope behavior
35
+ - out-of-scope items
36
+ - acceptance criteria
37
+ - risks and assumptions
38
+ - open questions
39
+ - next command
40
+