create-agentic-pdlc 1.0.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.
@@ -0,0 +1,77 @@
1
+ name: Trigger Implementation Agent
2
+
3
+ # Triggers when spec:approved is added to an issue (Gate 2)
4
+ # or when an architecture-violation issue is modified (Sentinel flow)
5
+ on:
6
+ issues:
7
+ types: [labeled]
8
+
9
+ jobs:
10
+ trigger-implementation-agent:
11
+ name: Trigger {{IMPLEMENTATION_AGENT_NAME}} for implementation
12
+ # Runs only when spec:approved is added
13
+ if: github.event.label.name == 'spec:approved'
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Comment on issue to trigger agent
17
+ uses: actions/github-script@v7
18
+ with:
19
+ github-token: ${{ secrets.GITHUB_TOKEN }}
20
+ script: |
21
+ const issueNumber = context.payload.issue.number;
22
+ const issueTitle = context.payload.issue.title;
23
+
24
+ const body = [
25
+ `{{AGENT_HANDLE}} The spec for this issue has been approved. Please implement it exactly as described in the body above.`,
26
+ '',
27
+ '**Mandatory steps before you begin:**',
28
+ '1. `git fetch origin && git checkout main && git pull` — always start from the current HEAD',
29
+ '2. Read `AGENTS.md` — mandatory rules for agents in this repository',
30
+ '3. Read `docs/pdlc.md` — Definition of Done and invariants reference',
31
+ '',
32
+ '**Rules:**',
33
+ '- Implement strictly what the Acceptance Criteria describes',
34
+ '- Run `{{TEST_COMMAND}}` before opening the Pull Request',
35
+ `- Include \`Closes #${issueNumber}\` in the PR body`,
36
+ '- Create a descriptive branch branching from `main`',
37
+ ].join('\n');
38
+
39
+ await github.rest.issues.createComment({
40
+ owner: context.repo.owner,
41
+ repo: context.repo.repo,
42
+ issue_number: issueNumber,
43
+ body,
44
+ });
45
+
46
+ trigger-agent-on-violation:
47
+ name: Trigger {{IMPLEMENTATION_AGENT_NAME}} for architecture violation
48
+ # Runs when architecture-violation is added (Sentinel flow)
49
+ if: github.event.label.name == 'architecture-violation'
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - name: Comment on issue to trigger agent
53
+ uses: actions/github-script@v7
54
+ with:
55
+ github-token: ${{ secrets.GITHUB_TOKEN }}
56
+ script: |
57
+ const issueNumber = context.payload.issue.number;
58
+
59
+ const body = [
60
+ `{{AGENT_HANDLE}} Please fix the architecture violation described in this issue.`,
61
+ '',
62
+ '**Mandatory steps before you begin:**',
63
+ '1. `git fetch origin && git checkout main && git pull` — always start from the current HEAD',
64
+ '2. Read `AGENTS.md` — mandatory rules for agents in this repository',
65
+ '',
66
+ '**Rules:**',
67
+ '- Fix only what the violation points out — do not refactor unrelated code',
68
+ '- Run `{{TEST_COMMAND}}` before opening the Pull Request',
69
+ `- Include \`Closes #${issueNumber}\` in the PR body`,
70
+ ].join('\n');
71
+
72
+ await github.rest.issues.createComment({
73
+ owner: context.repo.owner,
74
+ repo: context.repo.repo,
75
+ issue_number: issueNumber,
76
+ body,
77
+ });
@@ -0,0 +1,29 @@
1
+ name: Sentinel / CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+ push:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ validate:
11
+ name: Run tests and linters
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Setup environment
17
+ run: echo "Replace this with your language/toolchain setup (e.g., actions/setup-node)"
18
+
19
+ - name: Install dependencies
20
+ run: echo "Replace this with your package manager install command"
21
+
22
+ - name: Run Linters
23
+ run: echo "No tests/build needed."
24
+
25
+ - name: Build
26
+ run: echo "No tests/build needed."
27
+
28
+ - name: Run Tests
29
+ run: echo "No tests/build needed."
@@ -0,0 +1,150 @@
1
+ name: PDLC Board Automation
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, reopened, closed]
6
+ pull_request_review:
7
+ types: [submitted]
8
+
9
+ env:
10
+ PROJECT_ID: "{{PROJECT_ID}}"
11
+ STATUS_FIELD_ID: "{{STATUS_FIELD_ID}}"
12
+ STATUS_CODE_REVIEW: "{{ID_CODE_REVIEW}}"
13
+ STATUS_PULL_REQUEST: "{{ID_PULL_REQUEST}}"
14
+ STATUS_PRODUCAO: "{{ID_PRODUCAO}}"
15
+
16
+ jobs:
17
+ # PR Opened → Move linked issue to Code Review
18
+ move-card-on-pr-open:
19
+ name: Open PR → Code Review
20
+ if: github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - name: Move linked issue to Code Review
24
+ uses: actions/github-script@v7
25
+ with:
26
+ github-token: ${{ secrets.PROJECT_TOKEN }}
27
+ script: |
28
+ const prNumber = context.payload.pull_request.number;
29
+ const { owner, repo } = context.repo;
30
+
31
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
32
+ const body = pr.body ?? '';
33
+
34
+ // Extract issues linked via "Closes #N", "Fixes #N", "Resolves #N"
35
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)]
36
+ .map(m => parseInt(m[1]));
37
+
38
+ const moveItem = async (nodeId) => {
39
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
40
+ mutation($p: ID!, $c: ID!) {
41
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
42
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
43
+
44
+ await github.graphql(`
45
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
46
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
47
+ projectV2Item { id }
48
+ }
49
+ }`, {
50
+ p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
51
+ v: { singleSelectOptionId: process.env.STATUS_CODE_REVIEW }
52
+ });
53
+ };
54
+
55
+ if (linkedIssues.length > 0) {
56
+ for (const n of linkedIssues) {
57
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
58
+ await moveItem(issue.node_id);
59
+ console.log(`Issue #${n} → Code Review`);
60
+ }
61
+ } else {
62
+ await moveItem(pr.node_id);
63
+ console.log(`PR #${prNumber} → Code Review (no linked issue)`);
64
+ }
65
+
66
+ await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['pr:review'] }).catch(() => {});
67
+
68
+ # Review Approved → Pull Request
69
+ move-card-on-review-approved:
70
+ name: Approved PR → Pull Request
71
+ if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
72
+ runs-on: ubuntu-latest
73
+ steps:
74
+ - name: Move issue to Pull Request
75
+ uses: actions/github-script@v7
76
+ with:
77
+ github-token: ${{ secrets.PROJECT_TOKEN }}
78
+ script: |
79
+ const prNumber = context.payload.pull_request.number;
80
+ const { owner, repo } = context.repo;
81
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
82
+ const body = pr.body ?? '';
83
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)].map(m => parseInt(m[1]));
84
+
85
+ const moveItem = async (nodeId) => {
86
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
87
+ mutation($p: ID!, $c: ID!) {
88
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
89
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
90
+ await github.graphql(`
91
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
92
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
93
+ projectV2Item { id }
94
+ }
95
+ }`, { p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
96
+ v: { singleSelectOptionId: process.env.STATUS_PULL_REQUEST } });
97
+ };
98
+
99
+ if (linkedIssues.length > 0) {
100
+ for (const n of linkedIssues) {
101
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
102
+ await moveItem(issue.node_id);
103
+ }
104
+ } else {
105
+ await moveItem(pr.node_id);
106
+ }
107
+
108
+ try { await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: 'pr:review' }); } catch {}
109
+ await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['pr:approved'] }).catch(() => {});
110
+
111
+ # PR Merged → Production
112
+ move-card-on-pr-merge:
113
+ name: Merged PR → Production
114
+ if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - name: Move issue to Production
118
+ uses: actions/github-script@v7
119
+ with:
120
+ github-token: ${{ secrets.PROJECT_TOKEN }}
121
+ script: |
122
+ const prNumber = context.payload.pull_request.number;
123
+ const { owner, repo } = context.repo;
124
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
125
+ const body = pr.body ?? '';
126
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)].map(m => parseInt(m[1]));
127
+
128
+ const moveItem = async (nodeId) => {
129
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
130
+ mutation($p: ID!, $c: ID!) {
131
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
132
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
133
+ await github.graphql(`
134
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
135
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
136
+ projectV2Item { id }
137
+ }
138
+ }`, { p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
139
+ v: { singleSelectOptionId: process.env.STATUS_PRODUCAO } });
140
+ };
141
+
142
+ if (linkedIssues.length > 0) {
143
+ for (const n of linkedIssues) {
144
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
145
+ await moveItem(issue.node_id);
146
+ console.log(`Issue #${n} → Production`);
147
+ }
148
+ } else {
149
+ await moveItem(pr.node_id);
150
+ }
package/AGENTS.md ADDED
@@ -0,0 +1,48 @@
1
+ # agentic-pdlc — AI Agent Instructions
2
+
3
+ This template is the contract between the project and any external AI agent
4
+ (Claude Code, Cursor, Copilot, Jules, Codex, Sweep, etc.). Read this before committing any change.
5
+
6
+ ## Project Overview
7
+
8
+ The Agentic PDLC Framework is a lightweight, universal boilerplate that standardizes how your AI assistants (Claude, Cursor, Copilot, etc.) interpret tasks, respect your project's rules, and collaborate seamlessly from an idea to production.
9
+
10
+ **Structure:**
11
+ Markdown documentation and GitHub Actions YAMLs.
12
+
13
+ ## Before Any Change
14
+
15
+ ```bash
16
+ git fetch origin && git checkout main && git pull
17
+ ```
18
+
19
+ Always start from the current `main` HEAD. Never work over stale snapshots.
20
+
21
+ ## Invariants / Non-negotiable business rules
22
+
23
+ 1. **Keep it Lightweight & Universal**: Never introduce complex scripts (Node, Python, Bash) if a simple Markdown instruction or standard GitHub Action step suffices. The framework must remain easy for solo developers to adopt regardless of their tech stack.
24
+ 2. **Template Purity**: Never remove `{{SCREAMING_SNAKE_CASE}}` placeholders from the files inside the `templates/` folder. They must remain intact for the Setup Mode replacement logic to work.
25
+ 3. **No Placeholders in Root**: Conversely, files in the root (like `README.md` or `SETUP.md`) are for human readers on GitHub. Never leave unreplaced template variables in root documents.
26
+
27
+ ## Mandatory Workflow
28
+
29
+ 1. Read the issue entirely — understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
30
+ 2. Read `docs/pdlc.md` — understand the PDLC and the Definition of Done in this project.
31
+ 3. Read all files mentioned in the issue's technical context.
32
+ 4. Implement the **minimum viable change** that satisfies the ACs — do not refactor beyond scope.
33
+ 5. Run tests: `echo "No tests/build needed."`
34
+ 6. Create a Pull Request with `Closes #N` in the body — automation moves the board.
35
+
36
+ ## What NOT to do
37
+
38
+ - Never commit directly to `main`.
39
+ - Never open a PR without passing the tests.
40
+ - Never implement beyond the immediate scope of the issue.
41
+ - Never create future-proofing abstractions for hypothetical features.
42
+
43
+
44
+ ## Project Standards
45
+
46
+ - **Tests:** `echo "No tests/build needed."`
47
+ - **Lint/Types:** `echo "No tests/build needed."`
48
+ - **Build:** `echo "No tests/build needed."`
@@ -0,0 +1,18 @@
1
+ # Contributing to Agentic PDLC
2
+
3
+ First of all, thank you for considering contributing! We want to make the Agentic PDLC framework as seamless as possible across an ever-expanding multitude of AI coding environments.
4
+
5
+ ## How to Contribute
6
+
7
+ We welcome discussions, issues, and Pull Requests that directly help refine the interactions between developers and implementation agents. You can contribute by:
8
+
9
+ - **Reporting issues:** Let us know if a workflow or AI adapter is hallucinating or missing instructions.
10
+ - **Improving templates:** Fix grammatical errors or propose enhancements that make agent context more robust without polluting the prompt window.
11
+ - **Adding new adapters:** The AI space moves fast. If a new powerful AI agent emerges that requires specific adapter mechanisms, we'd love to see support for it. Keep it lean and ensure it leverages the universal `AGENTS.md`.
12
+
13
+ ## Submitting Pull Requests
14
+
15
+ 1. Fork the repository.
16
+ 2. Create a specific branch for your changes.
17
+ 3. Make your commits clear and atomic.
18
+ 4. Open a Pull Request pointing to `main`. Ensure your PR description spells out exactly why the change improves the agentic experience.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Rafael Costa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # 🤖 Agentic PDLC Framework
2
+
3
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)
5
+
6
+ > **Supercharge your solo development with a fully automated, AI-native Product Development Life Cycle (PDLC).**
7
+
8
+ Building software with AI agents is the future, but raw context windows aren't enough. Without structure, agents lose track, write inconsistent code, and break invariants.
9
+
10
+ The **Agentic PDLC Framework** is a lightweight, universal boilerplate that standardizes how your AI assistants (Claude, Cursor, Copilot, etc.) interpret tasks, respect your project's rules, and collaborate seamlessly from an idea to production.
11
+
12
+ ---
13
+
14
+ ## 🌟 Why use this framework?
15
+
16
+ - 🧠 **Contextual Perfection**: Gives every AI agent a single "source of truth" to abide by (`AGENTS.md`), preventing hallucinated dependencies or broken architectural rules.
17
+ - 🔄 **Automated Handoffs**: Built-in GitHub Actions automate the flow between brainstorming an idea and having an autonomous agent implement it.
18
+ - ⚡ **Multi-Assistant Support**: Works flawlessly whether you use Claude Code in the terminal, Cursor as your IDE, or autonomous sweeper agents.
19
+ - 🛠️ **Setup in Seconds**: Our interactive "Setup Mode" can scaffold your entire product context dynamically!
20
+
21
+ ---
22
+
23
+ ## 🏗️ How It Works: The Two Scopes
24
+
25
+ The Agentic PDLC bridges the gap between high-level human ideas and deterministic AI execution. It splits the workflow into two clear phases:
26
+
27
+ ### 🌊 1. Upstream (Idea → Spec)
28
+ You use conversational AI (e.g., **Claude Code**, **Cursor Chat**) as your brainstorming partner. Together, you flesh out user stories, acceptance criteria, and technical specifications until they are rock solid.
29
+
30
+ ### 🏭 2. Downstream (Spec → Production)
31
+ Once the spec is approved, autonomous implementation agents (e.g., **Jules**, **Sweep**, **Copilot Workspace**) pick up the task via an automated GitHub Project board flow. They execute the deterministic specs while being strictly governed by your project's invariants.
32
+
33
+ ---
34
+
35
+ ## 🤝 Universal Multi-Assistant Support
36
+
37
+ The framework relies on a universal source of truth (`AGENTS.md`), but uses elegant adapters to teach specific AI platforms how to read them.
38
+
39
+ | AI Assistant | Instruction File | How it Integrates |
40
+ |:---|:---|:---|
41
+ | **Claude Code** | `CLAUDE.md` + Claude Skill | Uses `adapters/claude-code/skill.md` *(Includes Auto-Setup Mode)* |
42
+ | **Cursor** | `.cursor/rules/*.md` | Uses `adapters/cursor/rules.md` |
43
+ | **GitHub Copilot** | `.github/copilot-instructions.md` | Uses `templates/.github/copilot-instructions.md` |
44
+ | **Codex / Antigravity** | `AGENTS.md` | Reads the contract natively |
45
+
46
+ *No matter which AI you pair with, they will all share the exact same context.*
47
+
48
+ ---
49
+
50
+ ## 📂 Expected Structure
51
+
52
+ Once initialized in your project, the framework provides the following layout:
53
+
54
+ ```text
55
+ your-project/
56
+ ├── AGENTS.md ← The universal contract mapping rules to any AI.
57
+ ├── docs/
58
+ │ └── pdlc.md ← The PDLC pipeline defining board columns and IDs.
59
+ └── .github/
60
+ └── workflows/
61
+ ├── project-automation.yml ← Automates GitHub Project card movement.
62
+ ├── agent-trigger.yml ← Wakes up your agent upon `spec:approved`.
63
+ └── ci.yml ← The Sentinel enforcing invariants and tests.
64
+ ```
65
+
66
+ ---
67
+
68
+ ## 🚀 Quick Start
69
+
70
+ Ready to build at the speed of thought? Scaffold the entire framework interactively without copy-pasting code!
71
+
72
+ Simply run our installer in the root of your project:
73
+
74
+ ```bash
75
+ npx create-agentic-pdlc
76
+ ```
77
+
78
+ > **💡 How it works:** The CLI acts as a bridge. It asks which AI assistant you prefer (e.g., Claude Code, Cursor), drops the required system instructions into your workspace, and hands control over to your AI. Your AI will then chat with you to customize your framework!
79
+
80
+ ---
81
+
82
+ ## ❤️ Contributing
83
+
84
+ We welcome improvements from other solo-founders and AI-engineers! Please check our **[Contributing Guidelines](CONTRIBUTING.md)** on how to submit PRs, add new AI platform adapters, or improve the documentation.
package/SETUP.md ADDED
@@ -0,0 +1,142 @@
1
+ # Setup Guide — Agentic PDLC Framework
2
+
3
+ Step-by-step guide to applying the framework to a new project.
4
+ Estimated time: 2-3 hours (including GitHub Projects setup).
5
+
6
+ ---
7
+
8
+ ## Prerequisites
9
+
10
+ - Target repository on GitHub (Public or GitHub Pro for branch protection)
11
+ - `gh` CLI installed and authenticated
12
+ - GitHub Projects enabled on your account/organization
13
+ - Implementation agent connected to the repository (e.g., Jules: github.com/google-labs/jules)
14
+
15
+ ---
16
+
17
+ ## Step 1 — Create the GitHub Project Board
18
+
19
+ ```bash
20
+ # Create the project
21
+ gh api graphql -f query='
22
+ mutation($owner: ID!, $title: String!) {
23
+ createProjectV2(input: {ownerId: $owner, title: $title}) {
24
+ projectV2 { id }
25
+ }
26
+ }' -f owner="YOUR_USER_NODE_ID" -f title="PDLC — Project Name"
27
+ ```
28
+
29
+ To get your user node ID:
30
+ ```bash
31
+ gh api graphql -f query='{ viewer { id } }' --jq '.data.viewer.id'
32
+ ```
33
+
34
+ After creation, **add the 10 columns** via the GitHub Projects UI or API.
35
+ Note down the `PROJECT_ID` and the `STATUS_FIELD_ID` for future steps.
36
+
37
+ ---
38
+
39
+ ## Step 2 — Create the Repository Labels
40
+
41
+ ```bash
42
+ REPO="owner/repo"
43
+ gh label create "spec:approved" --repo $REPO --color "0e8a16" --description "Spec approved — agent can implement"
44
+ gh label create "pr:review" --repo $REPO --color "e4e669" --description "PR awaiting code review"
45
+ gh label create "pr:approved" --repo $REPO --color "0e8a16" --description "PR approved, ready for merge"
46
+ gh label create "architecture-violation" --repo $REPO --color "d93f0b" --description "Invariant violation detected by CI"
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Step 3 — Scaffold the Framework Files
52
+
53
+ Instead of manually copying templates around, you can interactively inject the framework into your project using our open-source NPM tool.
54
+
55
+ Run the following command in the root of your project:
56
+
57
+ ```bash
58
+ npx create-agentic-pdlc
59
+ ```
60
+
61
+ The CLI will:
62
+ 1. Ask you which AI Agent you use (Claude Code, Cursor, etc.).
63
+ 2. Copy the system instructions pointing to our interactive Setup Mode.
64
+ 3. Automatically download the base templates to `.agentic-pdlc/templates/`.
65
+
66
+ Once the CLI finishes, it will instruct you to open your AI agent and run the **Setup Mode**. Your AI agent will then ask you the required project variables interactively and generate `AGENTS.md`, `docs/pdlc.md`, and the GitHub Actions for you!
67
+
68
+ ---
69
+
70
+ ## Step 4 — Configure GitHub Secrets
71
+
72
+ In the target repository: Settings → Secrets → Actions
73
+
74
+ | Secret | Description |
75
+ |---|---|
76
+ | `PROJECT_TOKEN` | GitHub PAT with `repo` + `project` scopes |
77
+
78
+ ---
79
+
80
+ ## Step 5 — Activate Branch Protection on `main`
81
+
82
+ Requires a public repository or GitHub Pro:
83
+
84
+ ```bash
85
+ gh api repos/OWNER/REPO/branches/main/protection \
86
+ --method PUT \
87
+ --input - <<'EOF'
88
+ {
89
+ "required_status_checks": {
90
+ "strict": true,
91
+ "checks": [{"context": "Sentinel / CI"}]
92
+ },
93
+ "enforce_admins": false,
94
+ "required_pull_request_reviews": {
95
+ "required_approving_review_count": 1,
96
+ "dismiss_stale_reviews": true
97
+ },
98
+ "restrictions": null,
99
+ "allow_force_pushes": false,
100
+ "allow_deletions": false
101
+ }
102
+ EOF
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Step 6 — Commit Artifacts
108
+
109
+ ```bash
110
+ git add AGENTS.md docs/pdlc.md .github/workflows/
111
+ git commit -m "chore: setup agentic-pdlc framework"
112
+ git push
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Step 7 — Populate the Initial Backlog
118
+
119
+ For each known idea or feature, create an issue using the convention:
120
+
121
+ ```bash
122
+ gh issue create \
123
+ --repo owner/repo \
124
+ --title "👤 US: [short description]" \
125
+ --body "Initial idea issue. Spec to be detailed."
126
+ ```
127
+
128
+ Move the issues to the `Idea` column on the board matching your setup.
129
+
130
+ ---
131
+
132
+ ## Final Verification Checklist
133
+
134
+ - [ ] Board has 10 columns fully configured
135
+ - [ ] Labels created in the repository
136
+ - [ ] `AGENTS.md` is present at the root, completely devoid of placeholders
137
+ - [ ] `docs/pdlc.md` has the correct IDs
138
+ - [ ] `project-automation.yml` is active (test with a dummy PR)
139
+ - [ ] `agent-trigger.yml` is active (test by adding `spec:approved` to an issue)
140
+ - [ ] `ci.yml` correctly runs tests and linters
141
+ - [ ] Branch protection active on `main`
142
+ - [ ] Implementation agent correctly connected to the repo
@@ -0,0 +1,5 @@
1
+ Add the following snippet to the `CLAUDE.md` file in the root of your target repository:
2
+
3
+ ```markdown
4
+ Run the `agentic-pdlc` skill to act as my upstream brainstorm and spec writing partner. If this repository is fresh, running the skill will automatically prompt the Setup Mode to populate `AGENTS.md`, `docs/pdlc.md`, and the automated `.github/workflows/`.
5
+ ```
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: agentic-pdlc
3
+ description: Orchestrates the Agentic Product Development Life Cycle (PDLC) upstream stages (Idea -> Spec) and includes an interactive Setup Mode to initialize the framework.
4
+ ---
5
+
6
+ # Agentic PDLC Orchestrator
7
+
8
+ You are the upstream brainstorm partner and orchestrator for the Agentic PDLC framework. Your role is primarily to define technical specs based on user ideas.
9
+
10
+ ## SETUP MODE
11
+
12
+ If the user invokes you in a new project, you must first check if the PDLC artifacts are present in the repository.
13
+ Specifically, check for:
14
+ - `AGENTS.md`
15
+ - `docs/pdlc.md`
16
+ - `.github/workflows/project-automation.yml`
17
+ - `.github/workflows/agent-trigger.yml`
18
+
19
+ If any of these files are missing, you are in **Setup Mode**. Do not proceed with feature requests until setup is complete.
20
+ 1. Acknowledge that the framework is not yet set up.
21
+ 2. Interactively ask the user for required values **one group at a time**:
22
+ - **Project basics:** Project Name, Description, Technical Stack (Structure).
23
+ - **Commands:** Test command, Lint command, Build command.
24
+ - **Invariants:** Critical business rules agents must never violate (e.g. Human-in-the-loop).
25
+ - **Board IDs:** PROJECT_ID, STATUS_FIELD_ID, column option IDs (provide standard PDLC options: Idea, Exploration, Brainstorming, Detail Solution, Approval, Development, Testing, Code Review, Pull Request, Production). Allow user to answer "skip", which means you leave the placeholders intact.
26
+ - **Implementation agent handle:** e.g., `@google-labs-jules`, or "none".
27
+ 3. Generate and write the missing files replacing the `{{SCREAMING_SNAKE_CASE}}` placeholders using the templates logic you know (usually they reside in standard Agentic PDLC templates).
28
+ 4. Offer to run the `gh` commands for labels (`spec:approved`, `pr:review`, `pr:approved`, `architecture-violation`).
29
+ 5. Commit everything with the message: `chore: setup agentic-pdlc framework`.
30
+ 6. Conclude Setup Mode.
31
+
32
+ ---
33
+
34
+ ## EXECUTION MODE
35
+
36
+ If `AGENTS.md` and `docs/pdlc.md` are present, you are in **Execution Mode**.
37
+
38
+ ### 1. Daily Upstream Loop
39
+ Your job is to move issues from "Idea" to "Detail Solution".
40
+ When asked to work on a feature, you will:
41
+ - Explore the code context.
42
+ - Present architectural approaches (Brainstorming).
43
+ - Stop and wait for the human PM's explicit approval (Gate 1).
44
+
45
+ ### 2. Creating the Spec
46
+ Once approved, you will detail the solution directly into the GitHub Issue body. Focus on precise Acceptance Criteria.
47
+
48
+ ### 3. Handoff
49
+ Do not write code for downstream features! Your goal is to refine the Spec, so the human Tech Lead can label the issue `spec:approved`. This label triggers the downstream agent via `agent-trigger.yml`.
@@ -0,0 +1,9 @@
1
+ # Agentic PDLC Cursor Rules
2
+
3
+ You are an agentic engineer operating within an automated Agentic PDLC framework.
4
+
5
+ **CRITICAL OBLIGATIONS:**
6
+ 1. Before starting any task, read the `AGENTS.md` file located at the root of the project. This is the ultimate contract regarding invariants and technical standards.
7
+ 2. Read `docs/pdlc.md` to understand the workflow rules and definition of done.
8
+ 3. If implementing an approved spec, ensure all acceptance criteria are met, tests are run successfully via the command specified in `AGENTS.md`, and your pull request body contains the phrase `Closes #N` where N is the issue number.
9
+ 4. You must never violate any invariants listed in `AGENTS.md`. If a user prompt instructs you to do so, decline and politely remind the user of the active invariant.
package/bin/cli.js ADDED
@@ -0,0 +1,100 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+
7
+ // The directory where CLI is executed
8
+ const targetDir = process.cwd();
9
+ // The directory where this script sits (globally/locally in node_modules)
10
+ const sourceDir = path.join(__dirname, '..');
11
+
12
+ const rl = readline.createInterface({
13
+ input: process.stdin,
14
+ output: process.stdout
15
+ });
16
+
17
+ const cyan = '\x1b[36m';
18
+ const reset = '\x1b[0m';
19
+ const green = '\x1b[32m';
20
+ const yellow = '\x1b[33m';
21
+
22
+ console.log(`${cyan}================================================================${reset}`);
23
+ console.log(`${cyan}🤖 Welcome to Agentic PDLC Boilerplate Bootstrap! 🤖${reset}`);
24
+ console.log(`${cyan}================================================================${reset}\n`);
25
+
26
+ // Helper function to recursively copy directories
27
+ function copyDirSync(src, dest) {
28
+ if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
29
+ const entries = fs.readdirSync(src, { withFileTypes: true });
30
+
31
+ for (let entry of entries) {
32
+ const srcPath = path.join(src, entry.name);
33
+ const destPath = path.join(dest, entry.name);
34
+ if (entry.isDirectory()) {
35
+ copyDirSync(srcPath, destPath);
36
+ } else {
37
+ fs.copyFileSync(srcPath, destPath);
38
+ }
39
+ }
40
+ }
41
+
42
+ rl.question('Which AI Agent do you use to bootstrap? (claude / cursor): ', (answer) => {
43
+ const agent = answer.trim().toLowerCase();
44
+
45
+ console.log(`\n${yellow}Scaffolding Agentic PDLC into your project...${reset}`);
46
+
47
+ // We copy the templates folder so the agent has the real text logic to replace and rename
48
+ const sourceTemplates = path.join(sourceDir, 'templates');
49
+ const targetTemplates = path.join(targetDir, '.agentic-pdlc', 'templates');
50
+
51
+ if (fs.existsSync(sourceTemplates)) {
52
+ copyDirSync(sourceTemplates, targetTemplates);
53
+ console.log(`✅ Templates copied to .agentic-pdlc/templates/`);
54
+ }
55
+
56
+ // Handle the specific setup instructions target
57
+ const claudeSetupSrc = path.join(sourceDir, 'adapters', 'claude-code', 'skill.md');
58
+ const cursorSetupSrc = path.join(sourceDir, 'adapters', 'cursor', 'rules.md');
59
+
60
+ if (agent === 'claude') {
61
+ if (fs.existsSync(claudeSetupSrc)) {
62
+ const dest = path.join(targetDir, '.claude.md');
63
+ fs.copyFileSync(claudeSetupSrc, dest);
64
+ console.log(`✅ Setup agent profile written to .claude.md`);
65
+ console.log(`\n${green}🎉 Done! To start the conversational setup:${reset}`);
66
+ console.log(`${cyan}\t1. Type 'claude'${reset}`);
67
+ console.log(`${cyan}\t2. It should automatically detect Setup Mode and prompt you.${reset}`);
68
+ console.log(`\nNote: The agent expects templates in .agentic-pdlc/templates.\n`);
69
+ } else {
70
+ console.error(`❌ Could not find claude instruction file at ${claudeSetupSrc}`);
71
+ }
72
+ } else if (agent === 'cursor') {
73
+ if (fs.existsSync(cursorSetupSrc)) {
74
+ // Create .cursorrules which has the general invariants
75
+ const dest = path.join(targetDir, '.cursorrules');
76
+ fs.copyFileSync(cursorSetupSrc, dest);
77
+
78
+ // Also copy skill.md as a setup prompt for cursor composer
79
+ const setupPromptDest = path.join(targetDir, '.agentic-pdlc', 'SETUP_PROMPT.md');
80
+ if (fs.existsSync(claudeSetupSrc)) fs.copyFileSync(claudeSetupSrc, setupPromptDest);
81
+
82
+ console.log(`✅ Default cursor rules written to .cursorrules`);
83
+ console.log(`✅ Framework Setup Instructions written to .agentic-pdlc/SETUP_PROMPT.md`);
84
+ console.log(`\n${green}🎉 Done! To start the conversational setup:${reset}`);
85
+ console.log(`${cyan}\t1. Open Cursor${reset}`);
86
+ console.log(`${cyan}\t2. Open Composer (Cmd+I or Cmd+L) and type: "@.agentic-pdlc/SETUP_PROMPT.md execute Setup Mode"${reset}\n`);
87
+ } else {
88
+ console.error(`❌ Could not find cursor instruction file at ${cursorSetupSrc}`);
89
+ }
90
+ } else {
91
+ // Generic fallback mapping
92
+ const dest = path.join(targetDir, '.agentic-setup-prompt.md');
93
+ fs.copyFileSync(claudeSetupSrc, dest);
94
+ console.log(`✅ Agent generic setup instructions written to .agentic-setup-prompt.md`);
95
+ console.log(`\n${green}🎉 Done! To start the conversational setup:${reset}`);
96
+ console.log(`${cyan}Provide the .agentic-setup-prompt.md file to your AI agent and ask it to execute Setup Mode!${reset}\n`);
97
+ }
98
+
99
+ rl.close();
100
+ });
package/docs/pdlc.md ADDED
@@ -0,0 +1,98 @@
1
+ # PDLC — agentic-pdlc
2
+
3
+ ## Board Columns
4
+
5
+ | Column | Meaning | Who moves the card |
6
+ |---|---|---|
7
+ | 💡 Idea | Backlog — every new issue lands here | Claude Code / Manual |
8
+ | 🔍 Exploration | Claude is analyzing code and context | Claude Code |
9
+ | 🧠 Brainstorming | Claude proposed approaches, awaiting PM gate | Claude Code |
10
+ | 📐 Detail Solution | Claude is writing the technical spec | Claude Code |
11
+ | ✅ Approval | Spec ready, awaiting `spec:approved` label | Claude Code |
12
+ | ⚙️ Development | Agent implementing the spec | Jules / Implementation Agent |
13
+ | 🧪 Testing | CI pipeline running | GitHub Actions |
14
+ | 👁 Code Review | PR opened, awaiting human review | GitHub Actions |
15
+ | 🔀 Pull Request | PR approved, awaiting merge | GitHub Actions |
16
+ | 🚀 Production | Merged | GitHub Actions |
17
+
18
+ <!--
19
+ Adapt columns as needed. The functional baseline is:
20
+ 💡 Idea → ⚙️ Development → 👁 Code Review → 🚀 Production
21
+ -->
22
+
23
+ ## Board Identifiers (GitHub Projects)
24
+
25
+ ```
26
+ PROJECT_ID = {{PROJECT_ID}}
27
+ STATUS_FIELD = {{STATUS_FIELD_ID}}
28
+ REPO = {{REPO_OWNER}}/{{REPO_NAME}}
29
+ ```
30
+
31
+ ## Column Option IDs
32
+
33
+ | Column | Option ID |
34
+ |---|---|
35
+ | 💡 Idea | `{{ID_IDEA}}` |
36
+ | 🔍 Exploration | `{{ID_EXPLORATION}}` |
37
+ | 🧠 Brainstorming | `{{ID_BRAINSTORMING}}` |
38
+ | 📐 Detail Solution | `{{ID_DETAIL}}` |
39
+ | ✅ Approval | `{{ID_APPROVAL}}` |
40
+ | ⚙️ Development | `{{ID_DEVELOPMENT}}` |
41
+ | 🧪 Testing | `{{ID_TESTING}}` |
42
+ | 👁 Code Review | `{{ID_CODE_REVIEW}}` |
43
+ | 🔀 Pull Request | `{{ID_PULL_REQUEST}}` |
44
+ | 🚀 Production | `{{ID_PRODUCTION}}` |
45
+
46
+ ## Agent × Phase Mapping
47
+
48
+ | Phase | Responsible |
49
+ |---|---|
50
+ | 💡 → 📐 (upstream) | Claude (or ideation agent) in conversational session |
51
+ | ⚙️ → 🔀 (downstream) | {{IMPLEMENTATION_AGENT}} (e.g. Jules `@google-labs-jules`) |
52
+ | 👁 Code Review | Human (you) |
53
+ | Automatic transitions | GitHub Actions |
54
+
55
+ ## Issue Title Conventions
56
+
57
+ ```
58
+ [icon] [PREFIX]: [short description, imperative tense]
59
+
60
+ 👤 US: user story
61
+ 🐛 BUG: bug
62
+ 🔧 TASK: operational task
63
+ 🔬 SPIKE: exploration/evaluation spike
64
+ ```
65
+
66
+ ## Labels
67
+
68
+ | Label | Entity | Color | Meaning |
69
+ |---|---|---|---|
70
+ | `spec:approved` | Issue | Green | Gate 2 — agent is cleared to implement |
71
+ | `pr:review` | PR | Yellow | Awaiting code review |
72
+ | `pr:approved` | PR | Green | Code review approved |
73
+
74
+ ## Approval Gates
75
+
76
+ **Gate 1 — PM/Ideation (Brainstorming):**
77
+ You comment on the issue approving one of the approaches proposed by the ideation agent.
78
+ Format: *"Approved — proceed with option X."*
79
+
80
+ **Gate 2 — Tech Lead (Spec):**
81
+ You add the `spec:approved` label to the issue after reviewing the technical spec in the body.
82
+ This triggers the implementation agent via `agent-trigger.yml`.
83
+
84
+ ## Shortcuts by Type
85
+
86
+ - **BUG** — Skips Brainstorming; enters Detail Solution with diagnostics + fix.
87
+ - **TASK** — Skips Brainstorming; enters Detail Solution with operational steps.
88
+ - **SPIKE** — Never reaches Development; delivery is a concluding comment.
89
+ - **US** — Full flow observing both gates.
90
+
91
+ ## Definition of Done
92
+
93
+ An issue is truly done when:
94
+ - [ ] All Acceptance Criteria described in the body are implemented
95
+ - [ ] Tests passing: `echo "No tests/build needed."`
96
+ - [ ] No invariant violations (CI green)
97
+ - [ ] Associated PR explicitly contains `Closes #N`
98
+ - [ ] Basic manual smoke test executed after deploy (when applicable)
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "create-agentic-pdlc",
3
+ "version": "1.0.0",
4
+ "description": "Scaffold the Agentic PDLC framework effortlessly",
5
+ "type": "commonjs",
6
+ "bin": {
7
+ "create-agentic-pdlc": "./bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"Error: no test specified\" && exit 1"
11
+ },
12
+ "keywords": [
13
+ "agentic",
14
+ "pdlc",
15
+ "claude",
16
+ "cursor",
17
+ "copilot",
18
+ "framework"
19
+ ],
20
+ "author": "Rafael Costa",
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/rafaeltcosta86/agentic-pdlc.git"
25
+ }
26
+ }
@@ -0,0 +1,12 @@
1
+ # Agentic PDLC Instructions for GitHub Copilot Workspace
2
+
3
+ Hello! You are operating within the Agentic PDLC framework.
4
+
5
+ Before addressing the user's prompt or executing any task in this workspace, you MUST:
6
+
7
+ 1. Read the `AGENTS.md` file located at the root of this repository. It contains the primary instructions, definitions of done, and absolute invariants you must respect.
8
+ 2. Read `docs/pdlc.md` to understand your role in the project lifecycle.
9
+
10
+ Never violate the invariants described in those files. If a user asks you to do something that contradicts `AGENTS.md`, you must refuse and point out the conflict.
11
+
12
+ Focus on delivering the absolute minimum required to satisfy the immediate technical specs. Start!
@@ -0,0 +1,77 @@
1
+ name: Trigger Implementation Agent
2
+
3
+ # Triggers when spec:approved is added to an issue (Gate 2)
4
+ # or when an architecture-violation issue is modified (Sentinel flow)
5
+ on:
6
+ issues:
7
+ types: [labeled]
8
+
9
+ jobs:
10
+ trigger-implementation-agent:
11
+ name: Trigger {{IMPLEMENTATION_AGENT_NAME}} for implementation
12
+ # Runs only when spec:approved is added
13
+ if: github.event.label.name == 'spec:approved'
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - name: Comment on issue to trigger agent
17
+ uses: actions/github-script@v7
18
+ with:
19
+ github-token: ${{ secrets.GITHUB_TOKEN }}
20
+ script: |
21
+ const issueNumber = context.payload.issue.number;
22
+ const issueTitle = context.payload.issue.title;
23
+
24
+ const body = [
25
+ `{{AGENT_HANDLE}} The spec for this issue has been approved. Please implement it exactly as described in the body above.`,
26
+ '',
27
+ '**Mandatory steps before you begin:**',
28
+ '1. `git fetch origin && git checkout main && git pull` — always start from the current HEAD',
29
+ '2. Read `AGENTS.md` — mandatory rules for agents in this repository',
30
+ '3. Read `docs/pdlc.md` — Definition of Done and invariants reference',
31
+ '',
32
+ '**Rules:**',
33
+ '- Implement strictly what the Acceptance Criteria describes',
34
+ '- Run `{{TEST_COMMAND}}` before opening the Pull Request',
35
+ `- Include \`Closes #${issueNumber}\` in the PR body`,
36
+ '- Create a descriptive branch branching from `main`',
37
+ ].join('\n');
38
+
39
+ await github.rest.issues.createComment({
40
+ owner: context.repo.owner,
41
+ repo: context.repo.repo,
42
+ issue_number: issueNumber,
43
+ body,
44
+ });
45
+
46
+ trigger-agent-on-violation:
47
+ name: Trigger {{IMPLEMENTATION_AGENT_NAME}} for architecture violation
48
+ # Runs when architecture-violation is added (Sentinel flow)
49
+ if: github.event.label.name == 'architecture-violation'
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - name: Comment on issue to trigger agent
53
+ uses: actions/github-script@v7
54
+ with:
55
+ github-token: ${{ secrets.GITHUB_TOKEN }}
56
+ script: |
57
+ const issueNumber = context.payload.issue.number;
58
+
59
+ const body = [
60
+ `{{AGENT_HANDLE}} Please fix the architecture violation described in this issue.`,
61
+ '',
62
+ '**Mandatory steps before you begin:**',
63
+ '1. `git fetch origin && git checkout main && git pull` — always start from the current HEAD',
64
+ '2. Read `AGENTS.md` — mandatory rules for agents in this repository',
65
+ '',
66
+ '**Rules:**',
67
+ '- Fix only what the violation points out — do not refactor unrelated code',
68
+ '- Run `{{TEST_COMMAND}}` before opening the Pull Request',
69
+ `- Include \`Closes #${issueNumber}\` in the PR body`,
70
+ ].join('\n');
71
+
72
+ await github.rest.issues.createComment({
73
+ owner: context.repo.owner,
74
+ repo: context.repo.repo,
75
+ issue_number: issueNumber,
76
+ body,
77
+ });
@@ -0,0 +1,29 @@
1
+ name: Sentinel / CI
2
+
3
+ on:
4
+ pull_request:
5
+ branches: [ main ]
6
+ push:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ validate:
11
+ name: Run tests and linters
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Setup environment
17
+ run: echo "Replace this with your language/toolchain setup (e.g., actions/setup-node)"
18
+
19
+ - name: Install dependencies
20
+ run: echo "Replace this with your package manager install command"
21
+
22
+ - name: Run Linters
23
+ run: {{LINT_COMMAND}}
24
+
25
+ - name: Build
26
+ run: {{BUILD_COMMAND}}
27
+
28
+ - name: Run Tests
29
+ run: {{TEST_COMMAND}}
@@ -0,0 +1,150 @@
1
+ name: PDLC Board Automation
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, reopened, closed]
6
+ pull_request_review:
7
+ types: [submitted]
8
+
9
+ env:
10
+ PROJECT_ID: "{{PROJECT_ID}}"
11
+ STATUS_FIELD_ID: "{{STATUS_FIELD_ID}}"
12
+ STATUS_CODE_REVIEW: "{{ID_CODE_REVIEW}}"
13
+ STATUS_PULL_REQUEST: "{{ID_PULL_REQUEST}}"
14
+ STATUS_PRODUCAO: "{{ID_PRODUCAO}}"
15
+
16
+ jobs:
17
+ # PR Opened → Move linked issue to Code Review
18
+ move-card-on-pr-open:
19
+ name: Open PR → Code Review
20
+ if: github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened')
21
+ runs-on: ubuntu-latest
22
+ steps:
23
+ - name: Move linked issue to Code Review
24
+ uses: actions/github-script@v7
25
+ with:
26
+ github-token: ${{ secrets.PROJECT_TOKEN }}
27
+ script: |
28
+ const prNumber = context.payload.pull_request.number;
29
+ const { owner, repo } = context.repo;
30
+
31
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
32
+ const body = pr.body ?? '';
33
+
34
+ // Extract issues linked via "Closes #N", "Fixes #N", "Resolves #N"
35
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)]
36
+ .map(m => parseInt(m[1]));
37
+
38
+ const moveItem = async (nodeId) => {
39
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
40
+ mutation($p: ID!, $c: ID!) {
41
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
42
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
43
+
44
+ await github.graphql(`
45
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
46
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
47
+ projectV2Item { id }
48
+ }
49
+ }`, {
50
+ p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
51
+ v: { singleSelectOptionId: process.env.STATUS_CODE_REVIEW }
52
+ });
53
+ };
54
+
55
+ if (linkedIssues.length > 0) {
56
+ for (const n of linkedIssues) {
57
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
58
+ await moveItem(issue.node_id);
59
+ console.log(`Issue #${n} → Code Review`);
60
+ }
61
+ } else {
62
+ await moveItem(pr.node_id);
63
+ console.log(`PR #${prNumber} → Code Review (no linked issue)`);
64
+ }
65
+
66
+ await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['pr:review'] }).catch(() => {});
67
+
68
+ # Review Approved → Pull Request
69
+ move-card-on-review-approved:
70
+ name: Approved PR → Pull Request
71
+ if: github.event_name == 'pull_request_review' && github.event.review.state == 'approved'
72
+ runs-on: ubuntu-latest
73
+ steps:
74
+ - name: Move issue to Pull Request
75
+ uses: actions/github-script@v7
76
+ with:
77
+ github-token: ${{ secrets.PROJECT_TOKEN }}
78
+ script: |
79
+ const prNumber = context.payload.pull_request.number;
80
+ const { owner, repo } = context.repo;
81
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
82
+ const body = pr.body ?? '';
83
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)].map(m => parseInt(m[1]));
84
+
85
+ const moveItem = async (nodeId) => {
86
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
87
+ mutation($p: ID!, $c: ID!) {
88
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
89
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
90
+ await github.graphql(`
91
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
92
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
93
+ projectV2Item { id }
94
+ }
95
+ }`, { p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
96
+ v: { singleSelectOptionId: process.env.STATUS_PULL_REQUEST } });
97
+ };
98
+
99
+ if (linkedIssues.length > 0) {
100
+ for (const n of linkedIssues) {
101
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
102
+ await moveItem(issue.node_id);
103
+ }
104
+ } else {
105
+ await moveItem(pr.node_id);
106
+ }
107
+
108
+ try { await github.rest.issues.removeLabel({ owner, repo, issue_number: prNumber, name: 'pr:review' }); } catch {}
109
+ await github.rest.issues.addLabels({ owner, repo, issue_number: prNumber, labels: ['pr:approved'] }).catch(() => {});
110
+
111
+ # PR Merged → Production
112
+ move-card-on-pr-merge:
113
+ name: Merged PR → Production
114
+ if: github.event_name == 'pull_request' && github.event.action == 'closed' && github.event.pull_request.merged == true
115
+ runs-on: ubuntu-latest
116
+ steps:
117
+ - name: Move issue to Production
118
+ uses: actions/github-script@v7
119
+ with:
120
+ github-token: ${{ secrets.PROJECT_TOKEN }}
121
+ script: |
122
+ const prNumber = context.payload.pull_request.number;
123
+ const { owner, repo } = context.repo;
124
+ const { data: pr } = await github.rest.pulls.get({ owner, repo, pull_number: prNumber });
125
+ const body = pr.body ?? '';
126
+ const linkedIssues = [...body.matchAll(/(?:Closes?|Fixes?|Resolves?)\s+#(\d+)/gi)].map(m => parseInt(m[1]));
127
+
128
+ const moveItem = async (nodeId) => {
129
+ const { addProjectV2ItemById: { item } } = await github.graphql(`
130
+ mutation($p: ID!, $c: ID!) {
131
+ addProjectV2ItemById(input: {projectId: $p, contentId: $c}) { item { id } }
132
+ }`, { p: process.env.PROJECT_ID, c: nodeId });
133
+ await github.graphql(`
134
+ mutation($p: ID!, $i: ID!, $f: ID!, $v: ProjectV2FieldValue!) {
135
+ updateProjectV2ItemFieldValue(input: {projectId: $p, itemId: $i, fieldId: $f, value: $v}) {
136
+ projectV2Item { id }
137
+ }
138
+ }`, { p: process.env.PROJECT_ID, i: item.id, f: process.env.STATUS_FIELD_ID,
139
+ v: { singleSelectOptionId: process.env.STATUS_PRODUCAO } });
140
+ };
141
+
142
+ if (linkedIssues.length > 0) {
143
+ for (const n of linkedIssues) {
144
+ const { data: issue } = await github.rest.issues.get({ owner, repo, issue_number: n });
145
+ await moveItem(issue.node_id);
146
+ console.log(`Issue #${n} → Production`);
147
+ }
148
+ } else {
149
+ await moveItem(pr.node_id);
150
+ }
@@ -0,0 +1,52 @@
1
+ # {{PROJECT_NAME}} — AI Agent Instructions
2
+
3
+ This template is the contract between the project and any external AI agent
4
+ (Claude Code, Cursor, Copilot, Jules, Codex, Sweep, etc.). Read this before committing any change.
5
+
6
+ ## Project Overview
7
+
8
+ {{PROJECT_DESCRIPTION}}
9
+
10
+ **Structure:**
11
+ {{PROJECT_STRUCTURE}}
12
+
13
+ ## Before Any Change
14
+
15
+ ```bash
16
+ git fetch origin && git checkout main && git pull
17
+ ```
18
+
19
+ Always start from the current `main` HEAD. Never work over stale snapshots.
20
+
21
+ ## Invariants / Non-negotiable business rules
22
+
23
+ {{INVARIANTS}}
24
+ <!-- Examples:
25
+ 1. **Human-in-the-Loop** — No external side-effect actions without explicit human approval.
26
+ 2. **Immutable Audit-Log** — It's strictly forbidden to UPDATE/DELETE on audit_log; INSERT only.
27
+ 3. **Credential Isolation** — Decryption occurs only in a specific service.
28
+ -->
29
+
30
+ ## Mandatory Workflow
31
+
32
+ 1. Read the issue entirely — understand its type (US/BUG/TASK/SPIKE) and the Acceptance Criteria.
33
+ 2. Read `docs/pdlc.md` — understand the PDLC and the Definition of Done in this project.
34
+ 3. Read all files mentioned in the issue's technical context.
35
+ 4. Implement the **minimum viable change** that satisfies the ACs — do not refactor beyond scope.
36
+ 5. Run tests: `{{TEST_COMMAND}}`
37
+ 6. Create a Pull Request with `Closes #N` in the body — automation moves the board.
38
+
39
+ ## What NOT to do
40
+
41
+ - Never commit directly to `main`.
42
+ - Never open a PR without passing the tests.
43
+ - Never implement beyond the immediate scope of the issue.
44
+ - Never create future-proofing abstractions for hypothetical features.
45
+ {{EXTRA_DONT}}
46
+
47
+ ## Project Standards
48
+
49
+ - **Tests:** `{{TEST_COMMAND}}`
50
+ - **Lint/Types:** `{{LINT_COMMAND}}`
51
+ - **Build:** `{{BUILD_COMMAND}}`
52
+ {{EXTRA_PATTERNS}}
@@ -0,0 +1,98 @@
1
+ # PDLC — {{PROJECT_NAME}}
2
+
3
+ ## Board Columns
4
+
5
+ | Column | Meaning | Who moves the card |
6
+ |---|---|---|
7
+ | 💡 Idea | Backlog — every new issue lands here | Claude Code / Manual |
8
+ | 🔍 Exploration | Claude is analyzing code and context | Claude Code |
9
+ | 🧠 Brainstorming | Claude proposed approaches, awaiting PM gate | Claude Code |
10
+ | 📐 Detail Solution | Claude is writing the technical spec | Claude Code |
11
+ | ✅ Approval | Spec ready, awaiting `spec:approved` label | Claude Code |
12
+ | ⚙️ Development | Agent implementing the spec | Jules / Implementation Agent |
13
+ | 🧪 Testing | CI pipeline running | GitHub Actions |
14
+ | 👁 Code Review | PR opened, awaiting human review | GitHub Actions |
15
+ | 🔀 Pull Request | PR approved, awaiting merge | GitHub Actions |
16
+ | 🚀 Production | Merged | GitHub Actions |
17
+
18
+ <!--
19
+ Adapt columns as needed. The functional baseline is:
20
+ 💡 Idea → ⚙️ Development → 👁 Code Review → 🚀 Production
21
+ -->
22
+
23
+ ## Board Identifiers (GitHub Projects)
24
+
25
+ ```
26
+ PROJECT_ID = {{PROJECT_ID}}
27
+ STATUS_FIELD = {{STATUS_FIELD_ID}}
28
+ REPO = {{REPO_OWNER}}/{{REPO_NAME}}
29
+ ```
30
+
31
+ ## Column Option IDs
32
+
33
+ | Column | Option ID |
34
+ |---|---|
35
+ | 💡 Idea | `{{ID_IDEA}}` |
36
+ | 🔍 Exploration | `{{ID_EXPLORATION}}` |
37
+ | 🧠 Brainstorming | `{{ID_BRAINSTORMING}}` |
38
+ | 📐 Detail Solution | `{{ID_DETAIL}}` |
39
+ | ✅ Approval | `{{ID_APPROVAL}}` |
40
+ | ⚙️ Development | `{{ID_DEVELOPMENT}}` |
41
+ | 🧪 Testing | `{{ID_TESTING}}` |
42
+ | 👁 Code Review | `{{ID_CODE_REVIEW}}` |
43
+ | 🔀 Pull Request | `{{ID_PULL_REQUEST}}` |
44
+ | 🚀 Production | `{{ID_PRODUCTION}}` |
45
+
46
+ ## Agent × Phase Mapping
47
+
48
+ | Phase | Responsible |
49
+ |---|---|
50
+ | 💡 → 📐 (upstream) | Claude (or ideation agent) in conversational session |
51
+ | ⚙️ → 🔀 (downstream) | {{IMPLEMENTATION_AGENT}} (e.g. Jules `@google-labs-jules`) |
52
+ | 👁 Code Review | Human (you) |
53
+ | Automatic transitions | GitHub Actions |
54
+
55
+ ## Issue Title Conventions
56
+
57
+ ```
58
+ [icon] [PREFIX]: [short description, imperative tense]
59
+
60
+ 👤 US: user story
61
+ 🐛 BUG: bug
62
+ 🔧 TASK: operational task
63
+ 🔬 SPIKE: exploration/evaluation spike
64
+ ```
65
+
66
+ ## Labels
67
+
68
+ | Label | Entity | Color | Meaning |
69
+ |---|---|---|---|
70
+ | `spec:approved` | Issue | Green | Gate 2 — agent is cleared to implement |
71
+ | `pr:review` | PR | Yellow | Awaiting code review |
72
+ | `pr:approved` | PR | Green | Code review approved |
73
+
74
+ ## Approval Gates
75
+
76
+ **Gate 1 — PM/Ideation (Brainstorming):**
77
+ You comment on the issue approving one of the approaches proposed by the ideation agent.
78
+ Format: *"Approved — proceed with option X."*
79
+
80
+ **Gate 2 — Tech Lead (Spec):**
81
+ You add the `spec:approved` label to the issue after reviewing the technical spec in the body.
82
+ This triggers the implementation agent via `agent-trigger.yml`.
83
+
84
+ ## Shortcuts by Type
85
+
86
+ - **BUG** — Skips Brainstorming; enters Detail Solution with diagnostics + fix.
87
+ - **TASK** — Skips Brainstorming; enters Detail Solution with operational steps.
88
+ - **SPIKE** — Never reaches Development; delivery is a concluding comment.
89
+ - **US** — Full flow observing both gates.
90
+
91
+ ## Definition of Done
92
+
93
+ An issue is truly done when:
94
+ - [ ] All Acceptance Criteria described in the body are implemented
95
+ - [ ] Tests passing: `{{TEST_COMMAND}}`
96
+ - [ ] No invariant violations (CI green)
97
+ - [ ] Associated PR explicitly contains `Closes #N`
98
+ - [ ] Basic manual smoke test executed after deploy (when applicable)