methodology-framework 0.1.0__tar.gz
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.
- methodology_framework-0.1.0/LICENSE +21 -0
- methodology_framework-0.1.0/PKG-INFO +264 -0
- methodology_framework-0.1.0/README.md +243 -0
- methodology_framework-0.1.0/pyproject.toml +54 -0
- methodology_framework-0.1.0/setup.cfg +4 -0
- methodology_framework-0.1.0/src/methodology_framework/__init__.py +17 -0
- methodology_framework-0.1.0/src/methodology_framework/__main__.py +28 -0
- methodology_framework-0.1.0/src/methodology_framework/bootstrap_jira.py +427 -0
- methodology_framework-0.1.0/src/methodology_framework/build_playbook.py +172 -0
- methodology_framework-0.1.0/src/methodology_framework/jira_shapes/__init__.py +0 -0
- methodology_framework-0.1.0/src/methodology_framework/jira_shapes/automation_rules.yaml +85 -0
- methodology_framework-0.1.0/src/methodology_framework/jira_shapes/custom_fields.yaml +44 -0
- methodology_framework-0.1.0/src/methodology_framework/jira_shapes/workflow.yaml +135 -0
- methodology_framework-0.1.0/src/methodology_framework/playbooks/scrum-router.body.md +217 -0
- methodology_framework-0.1.0/src/methodology_framework/populate_acus.py +210 -0
- methodology_framework-0.1.0/src/methodology_framework/register_playbook_with_devin.py +294 -0
- methodology_framework-0.1.0/src/methodology_framework/specs/devin-story-format.md +536 -0
- methodology_framework-0.1.0/src/methodology_framework/sync_stories_to_jira.py +1087 -0
- methodology_framework-0.1.0/src/methodology_framework/templates/github_workflows/populate-story-acus-caller.yml +29 -0
- methodology_framework-0.1.0/src/methodology_framework/templates/story.md +152 -0
- methodology_framework-0.1.0/src/methodology_framework.egg-info/PKG-INFO +264 -0
- methodology_framework-0.1.0/src/methodology_framework.egg-info/SOURCES.txt +29 -0
- methodology_framework-0.1.0/src/methodology_framework.egg-info/dependency_links.txt +1 -0
- methodology_framework-0.1.0/src/methodology_framework.egg-info/requires.txt +11 -0
- methodology_framework-0.1.0/src/methodology_framework.egg-info/top_level.txt +1 -0
- methodology_framework-0.1.0/tests/test_bootstrap_jira.py +288 -0
- methodology_framework-0.1.0/tests/test_build_playbook.py +145 -0
- methodology_framework-0.1.0/tests/test_populate_acus.py +148 -0
- methodology_framework-0.1.0/tests/test_register_playbook_with_devin.py +434 -0
- methodology_framework-0.1.0/tests/test_sync_stories_to_jira.py +1441 -0
- methodology_framework-0.1.0/tests/test_workflows.py +100 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 whiteout59
|
|
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.
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: methodology-framework
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs.
|
|
5
|
+
Author: whiteout59
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Requires-Python: >=3.12
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: requests<3,>=2.31
|
|
11
|
+
Requires-Dist: python-frontmatter<2,>=1.1
|
|
12
|
+
Requires-Dist: pyyaml<7,>=6.0
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: pytest<9,>=8.0; extra == "dev"
|
|
15
|
+
Requires-Dist: requests-mock<2,>=1.12; extra == "dev"
|
|
16
|
+
Requires-Dist: ruff==0.15.14; extra == "dev"
|
|
17
|
+
Requires-Dist: mypy<2,>=1.10; extra == "dev"
|
|
18
|
+
Requires-Dist: types-requests<3,>=2.31; extra == "dev"
|
|
19
|
+
Requires-Dist: types-PyYAML<7,>=6.0; extra == "dev"
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
|
|
22
|
+
# methodology-framework
|
|
23
|
+
|
|
24
|
+
Portable process tooling for agent-driven delivery -- scripts, playbooks, templates, and specs.
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install -e .
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Package contents
|
|
33
|
+
|
|
34
|
+
- `methodology_framework.sync_stories_to_jira` -- one-way repo-to-Jira story sync
|
|
35
|
+
- `methodology_framework.build_playbook` -- build a concrete playbook from a parameterized body + bindings
|
|
36
|
+
- `methodology_framework.register_playbook_with_devin` -- register a rendered playbook with Devin's API
|
|
37
|
+
- `methodology_framework/playbooks/` -- parameterized playbook bodies (package data)
|
|
38
|
+
- `methodology_framework/templates/` -- story and process templates (package data)
|
|
39
|
+
- `methodology_framework/specs/` -- format specs (package data)
|
|
40
|
+
- `methodology_framework.bootstrap_jira` -- bootstrap a Jira project with the canonical workflow, custom fields, and automation rules
|
|
41
|
+
- `methodology_framework/jira_shapes/` -- canonical Jira shape definitions (YAML, package data)
|
|
42
|
+
|
|
43
|
+
## Jira Bootstrap
|
|
44
|
+
|
|
45
|
+
Adopting projects provision their Jira project shape from a single CLI command
|
|
46
|
+
instead of manually configuring 30+ admin UI screens.
|
|
47
|
+
|
|
48
|
+
### Prerequisites
|
|
49
|
+
|
|
50
|
+
- Python 3.12+
|
|
51
|
+
- `pip install methodology-framework` (or `pip install -e .` from source)
|
|
52
|
+
- For `--apply` mode: `JIRA_ADMIN_TOKEN` environment variable set to a Jira
|
|
53
|
+
admin API token or OAuth Bearer token
|
|
54
|
+
|
|
55
|
+
### Usage
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Dry-run (default) — print what would be applied, no side-effects
|
|
59
|
+
python -m methodology_framework bootstrap-jira \
|
|
60
|
+
--project-key=MYPROJ \
|
|
61
|
+
--jira-host=myorg.atlassian.net \
|
|
62
|
+
--dry-run
|
|
63
|
+
|
|
64
|
+
# Export — emit an importable config bundle (YAML); no API calls
|
|
65
|
+
python -m methodology_framework bootstrap-jira \
|
|
66
|
+
--project-key=MYPROJ \
|
|
67
|
+
--jira-host=myorg.atlassian.net \
|
|
68
|
+
--export /tmp/jira-bundle.yaml
|
|
69
|
+
|
|
70
|
+
# Apply — provision the Jira project via admin API
|
|
71
|
+
export JIRA_ADMIN_TOKEN="<your-token>"
|
|
72
|
+
python -m methodology_framework bootstrap-jira \
|
|
73
|
+
--project-key=MYPROJ \
|
|
74
|
+
--jira-host=myorg.atlassian.net \
|
|
75
|
+
--apply
|
|
76
|
+
|
|
77
|
+
# Apply with --force to skip confirmation prompts
|
|
78
|
+
python -m methodology_framework bootstrap-jira \
|
|
79
|
+
--project-key=MYPROJ \
|
|
80
|
+
--jira-host=myorg.atlassian.net \
|
|
81
|
+
--apply --force
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Flags
|
|
85
|
+
|
|
86
|
+
| Flag | Required | Description |
|
|
87
|
+
|------|----------|-------------|
|
|
88
|
+
| `--project-key` | Yes | Jira project key (e.g. `SCRUM`). Substituted for `{{PROJECT_KEY}}` in shape defs. |
|
|
89
|
+
| `--jira-host` | Yes | Jira Cloud host (e.g. `myorg.atlassian.net`). No `https://` prefix. |
|
|
90
|
+
| `--dry-run` | No | Print what would be applied (default if no mode specified). |
|
|
91
|
+
| `--apply` | No | POST/PUT to Jira admin API. Requires `JIRA_ADMIN_TOKEN` env var. |
|
|
92
|
+
| `--export <path>` | No | Emit importable config bundle at `<path>`. |
|
|
93
|
+
| `--force` | No | Skip confirmation prompts during `--apply`. |
|
|
94
|
+
|
|
95
|
+
### Environment variables
|
|
96
|
+
|
|
97
|
+
| Variable | When needed | Description |
|
|
98
|
+
|----------|-------------|-------------|
|
|
99
|
+
| `JIRA_ADMIN_TOKEN` | `--apply` mode | Jira admin API token. **Never** accepted as a CLI flag. |
|
|
100
|
+
|
|
101
|
+
### Shape definitions
|
|
102
|
+
|
|
103
|
+
The three canonical shape files shipped as package data:
|
|
104
|
+
|
|
105
|
+
- `jira_shapes/workflow.yaml` — workflow statuses (To Do, Ready for AI agent,
|
|
106
|
+
In Progress, In Review, Waiting, Blocked, Done, Won't do) and transitions
|
|
107
|
+
with actor permissions
|
|
108
|
+
- `jira_shapes/custom_fields.yaml` — Story File (URL), Requirement IDs
|
|
109
|
+
(labels), Agent Estimate (number)
|
|
110
|
+
- `jira_shapes/automation_rules.yaml` — PR-title-key auto-transition,
|
|
111
|
+
dependency resolution, BLOCKED protection
|
|
112
|
+
|
|
113
|
+
For full methodology context see the methodology requirements doc § 4.13.3
|
|
114
|
+
("Jira Bootstrap CLI").
|
|
115
|
+
|
|
116
|
+
## Adopter Integration
|
|
117
|
+
|
|
118
|
+
Adopting projects consume the methodology framework's CI pipelines via
|
|
119
|
+
**reusable GitHub Actions workflows**. Instead of copying workflow YAML
|
|
120
|
+
into each repo, adopters write a thin caller that references the
|
|
121
|
+
framework's workflows by SemVer tag.
|
|
122
|
+
|
|
123
|
+
> **Version pinning requirement:** adopters MUST pin to a specific tag
|
|
124
|
+
> (`@v0.X.Y`), never `@main`. The framework version must be explicit
|
|
125
|
+
> in the caller so updates are deliberate, not silent. This matches the
|
|
126
|
+
> version-pinning model per methodology requirements § 4.13.
|
|
127
|
+
|
|
128
|
+
### Story sync workflow
|
|
129
|
+
|
|
130
|
+
Syncs story `.md` files from the adopter's repo to Jira. Create
|
|
131
|
+
`.github/workflows/sync.yml` in the adopter repo:
|
|
132
|
+
|
|
133
|
+
```yaml
|
|
134
|
+
name: Sync stories to Jira
|
|
135
|
+
|
|
136
|
+
on:
|
|
137
|
+
push:
|
|
138
|
+
branches: [main]
|
|
139
|
+
paths:
|
|
140
|
+
- "docs/stories/**/*.md"
|
|
141
|
+
workflow_dispatch:
|
|
142
|
+
inputs:
|
|
143
|
+
mode:
|
|
144
|
+
description: "Sync mode"
|
|
145
|
+
required: true
|
|
146
|
+
default: "since-ref"
|
|
147
|
+
type: choice
|
|
148
|
+
options:
|
|
149
|
+
- since-ref
|
|
150
|
+
- all
|
|
151
|
+
|
|
152
|
+
jobs:
|
|
153
|
+
sync:
|
|
154
|
+
uses: whiteout59/methodology-framework/.github/workflows/sync.yml@v0.1.0
|
|
155
|
+
with:
|
|
156
|
+
project_key: SCRUM
|
|
157
|
+
repo: whiteout59/centralized-pipeline-ui
|
|
158
|
+
story_path_pattern: "docs/stories/{phase1,phase2}/**/*.md"
|
|
159
|
+
cf_story_file: "customfield_10073"
|
|
160
|
+
cf_requirement_ids: "customfield_10141"
|
|
161
|
+
cf_agent_estimate: "customfield_10074"
|
|
162
|
+
mode: ${{ github.event.inputs.mode || 'since-ref' }}
|
|
163
|
+
jira_base_url: "https://myorg.atlassian.net"
|
|
164
|
+
jira_user_email: "devin-sync@myorg.atlassian.net"
|
|
165
|
+
secrets:
|
|
166
|
+
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The `mode` input defaults to `since-ref` for routine push-triggered
|
|
170
|
+
runs (preserves the 250-story scale guard). Pass `mode: all` explicitly
|
|
171
|
+
for nightly or `workflow_dispatch` full-corpus syncs.
|
|
172
|
+
|
|
173
|
+
> **Secrets forwarding:** the caller's `secrets:` block must explicitly
|
|
174
|
+
> map each secret the reusable workflow declares. Secrets are NOT
|
|
175
|
+
> inherited by default in reusable workflows. Using `secrets: inherit`
|
|
176
|
+
> works but is brittle — prefer explicit mapping.
|
|
177
|
+
|
|
178
|
+
### Playbook build + register workflow
|
|
179
|
+
|
|
180
|
+
Builds a concrete playbook from a parameterized body + bindings file,
|
|
181
|
+
then registers it with Devin's API. Create
|
|
182
|
+
`.github/workflows/build-and-register.yml` in the adopter repo:
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
name: Build and register playbook
|
|
186
|
+
|
|
187
|
+
on:
|
|
188
|
+
push:
|
|
189
|
+
branches: [main]
|
|
190
|
+
paths:
|
|
191
|
+
- "methodology/playbooks/*.body.md"
|
|
192
|
+
- "docs/jira-pickup-config.md"
|
|
193
|
+
workflow_dispatch:
|
|
194
|
+
|
|
195
|
+
jobs:
|
|
196
|
+
build-and-register:
|
|
197
|
+
uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
|
|
198
|
+
with:
|
|
199
|
+
playbook_body_path: "methodology/playbooks/scrum-router.body.md"
|
|
200
|
+
bindings_path: "docs/jira-pickup-config.md"
|
|
201
|
+
secrets:
|
|
202
|
+
DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
> **Nesting limit:** GitHub allows reusable workflow nesting up to
|
|
206
|
+
> 4 levels deep. If your repo wraps these workflows in another
|
|
207
|
+
> caller layer, verify the total nesting depth stays within limits.
|
|
208
|
+
|
|
209
|
+
## PyPI Publishing
|
|
210
|
+
|
|
211
|
+
The package is published to PyPI automatically via OIDC Trusted Publishers
|
|
212
|
+
when a SemVer tag is pushed:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
git tag v0.1.0
|
|
216
|
+
git push origin v0.1.0
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The `pypi-release.yml` workflow builds and publishes using
|
|
220
|
+
`pypa/gh-action-pypi-publish` in OIDC mode -- no `PYPI_API_TOKEN` secret
|
|
221
|
+
is needed. The job uses the `pypi` GitHub environment for protection rules.
|
|
222
|
+
|
|
223
|
+
**Operator setup (one-time):** bind the PyPI project `methodology-framework`
|
|
224
|
+
to the GitHub repo `whiteout59/methodology-framework`, workflow
|
|
225
|
+
`pypi-release.yml`, environment `pypi` at
|
|
226
|
+
[PyPI Trusted Publishers](https://pypi.org/manage/account/publishing/).
|
|
227
|
+
|
|
228
|
+
## Cost tracking via `agent_acus`
|
|
229
|
+
|
|
230
|
+
The methodology's post-execution notes include an `agent_acus` field that
|
|
231
|
+
records per-story compute cost. Since agents cannot self-report ACU
|
|
232
|
+
consumption mid-session, a post-merge populator workflow backfills the
|
|
233
|
+
value from the Devin API after the session completes.
|
|
234
|
+
|
|
235
|
+
**Adopter wiring (3 steps):**
|
|
236
|
+
|
|
237
|
+
1. Copy the template caller into your repo:
|
|
238
|
+
```bash
|
|
239
|
+
cp "$(python -c "import methodology_framework; import pathlib; \
|
|
240
|
+
print(pathlib.Path(methodology_framework.__file__).parent / \
|
|
241
|
+
'templates/github_workflows/populate-story-acus-caller.yml')")" \
|
|
242
|
+
.github/workflows/populate-story-acus.yml
|
|
243
|
+
```
|
|
244
|
+
2. Set the `DEVIN_API_TOKEN` repo secret (Settings > Secrets and
|
|
245
|
+
variables > Actions > New repository secret).
|
|
246
|
+
3. Pin the framework version in the caller's `uses:` line.
|
|
247
|
+
|
|
248
|
+
The caller fires on merged PRs that touch story files, invokes the
|
|
249
|
+
reusable `populate-story-acus.yml` workflow, and opens a follow-on PR
|
|
250
|
+
with the populated ACU values.
|
|
251
|
+
|
|
252
|
+
## Development
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
pip install -e ".[dev]"
|
|
256
|
+
pytest tests/ -v
|
|
257
|
+
ruff check src/methodology_framework
|
|
258
|
+
ruff format --check src/methodology_framework
|
|
259
|
+
mypy --strict src/methodology_framework
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
## License
|
|
263
|
+
|
|
264
|
+
Apache-2.0
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# methodology-framework
|
|
2
|
+
|
|
3
|
+
Portable process tooling for agent-driven delivery -- scripts, playbooks, templates, and specs.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install -e .
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Package contents
|
|
12
|
+
|
|
13
|
+
- `methodology_framework.sync_stories_to_jira` -- one-way repo-to-Jira story sync
|
|
14
|
+
- `methodology_framework.build_playbook` -- build a concrete playbook from a parameterized body + bindings
|
|
15
|
+
- `methodology_framework.register_playbook_with_devin` -- register a rendered playbook with Devin's API
|
|
16
|
+
- `methodology_framework/playbooks/` -- parameterized playbook bodies (package data)
|
|
17
|
+
- `methodology_framework/templates/` -- story and process templates (package data)
|
|
18
|
+
- `methodology_framework/specs/` -- format specs (package data)
|
|
19
|
+
- `methodology_framework.bootstrap_jira` -- bootstrap a Jira project with the canonical workflow, custom fields, and automation rules
|
|
20
|
+
- `methodology_framework/jira_shapes/` -- canonical Jira shape definitions (YAML, package data)
|
|
21
|
+
|
|
22
|
+
## Jira Bootstrap
|
|
23
|
+
|
|
24
|
+
Adopting projects provision their Jira project shape from a single CLI command
|
|
25
|
+
instead of manually configuring 30+ admin UI screens.
|
|
26
|
+
|
|
27
|
+
### Prerequisites
|
|
28
|
+
|
|
29
|
+
- Python 3.12+
|
|
30
|
+
- `pip install methodology-framework` (or `pip install -e .` from source)
|
|
31
|
+
- For `--apply` mode: `JIRA_ADMIN_TOKEN` environment variable set to a Jira
|
|
32
|
+
admin API token or OAuth Bearer token
|
|
33
|
+
|
|
34
|
+
### Usage
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Dry-run (default) — print what would be applied, no side-effects
|
|
38
|
+
python -m methodology_framework bootstrap-jira \
|
|
39
|
+
--project-key=MYPROJ \
|
|
40
|
+
--jira-host=myorg.atlassian.net \
|
|
41
|
+
--dry-run
|
|
42
|
+
|
|
43
|
+
# Export — emit an importable config bundle (YAML); no API calls
|
|
44
|
+
python -m methodology_framework bootstrap-jira \
|
|
45
|
+
--project-key=MYPROJ \
|
|
46
|
+
--jira-host=myorg.atlassian.net \
|
|
47
|
+
--export /tmp/jira-bundle.yaml
|
|
48
|
+
|
|
49
|
+
# Apply — provision the Jira project via admin API
|
|
50
|
+
export JIRA_ADMIN_TOKEN="<your-token>"
|
|
51
|
+
python -m methodology_framework bootstrap-jira \
|
|
52
|
+
--project-key=MYPROJ \
|
|
53
|
+
--jira-host=myorg.atlassian.net \
|
|
54
|
+
--apply
|
|
55
|
+
|
|
56
|
+
# Apply with --force to skip confirmation prompts
|
|
57
|
+
python -m methodology_framework bootstrap-jira \
|
|
58
|
+
--project-key=MYPROJ \
|
|
59
|
+
--jira-host=myorg.atlassian.net \
|
|
60
|
+
--apply --force
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Flags
|
|
64
|
+
|
|
65
|
+
| Flag | Required | Description |
|
|
66
|
+
|------|----------|-------------|
|
|
67
|
+
| `--project-key` | Yes | Jira project key (e.g. `SCRUM`). Substituted for `{{PROJECT_KEY}}` in shape defs. |
|
|
68
|
+
| `--jira-host` | Yes | Jira Cloud host (e.g. `myorg.atlassian.net`). No `https://` prefix. |
|
|
69
|
+
| `--dry-run` | No | Print what would be applied (default if no mode specified). |
|
|
70
|
+
| `--apply` | No | POST/PUT to Jira admin API. Requires `JIRA_ADMIN_TOKEN` env var. |
|
|
71
|
+
| `--export <path>` | No | Emit importable config bundle at `<path>`. |
|
|
72
|
+
| `--force` | No | Skip confirmation prompts during `--apply`. |
|
|
73
|
+
|
|
74
|
+
### Environment variables
|
|
75
|
+
|
|
76
|
+
| Variable | When needed | Description |
|
|
77
|
+
|----------|-------------|-------------|
|
|
78
|
+
| `JIRA_ADMIN_TOKEN` | `--apply` mode | Jira admin API token. **Never** accepted as a CLI flag. |
|
|
79
|
+
|
|
80
|
+
### Shape definitions
|
|
81
|
+
|
|
82
|
+
The three canonical shape files shipped as package data:
|
|
83
|
+
|
|
84
|
+
- `jira_shapes/workflow.yaml` — workflow statuses (To Do, Ready for AI agent,
|
|
85
|
+
In Progress, In Review, Waiting, Blocked, Done, Won't do) and transitions
|
|
86
|
+
with actor permissions
|
|
87
|
+
- `jira_shapes/custom_fields.yaml` — Story File (URL), Requirement IDs
|
|
88
|
+
(labels), Agent Estimate (number)
|
|
89
|
+
- `jira_shapes/automation_rules.yaml` — PR-title-key auto-transition,
|
|
90
|
+
dependency resolution, BLOCKED protection
|
|
91
|
+
|
|
92
|
+
For full methodology context see the methodology requirements doc § 4.13.3
|
|
93
|
+
("Jira Bootstrap CLI").
|
|
94
|
+
|
|
95
|
+
## Adopter Integration
|
|
96
|
+
|
|
97
|
+
Adopting projects consume the methodology framework's CI pipelines via
|
|
98
|
+
**reusable GitHub Actions workflows**. Instead of copying workflow YAML
|
|
99
|
+
into each repo, adopters write a thin caller that references the
|
|
100
|
+
framework's workflows by SemVer tag.
|
|
101
|
+
|
|
102
|
+
> **Version pinning requirement:** adopters MUST pin to a specific tag
|
|
103
|
+
> (`@v0.X.Y`), never `@main`. The framework version must be explicit
|
|
104
|
+
> in the caller so updates are deliberate, not silent. This matches the
|
|
105
|
+
> version-pinning model per methodology requirements § 4.13.
|
|
106
|
+
|
|
107
|
+
### Story sync workflow
|
|
108
|
+
|
|
109
|
+
Syncs story `.md` files from the adopter's repo to Jira. Create
|
|
110
|
+
`.github/workflows/sync.yml` in the adopter repo:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
name: Sync stories to Jira
|
|
114
|
+
|
|
115
|
+
on:
|
|
116
|
+
push:
|
|
117
|
+
branches: [main]
|
|
118
|
+
paths:
|
|
119
|
+
- "docs/stories/**/*.md"
|
|
120
|
+
workflow_dispatch:
|
|
121
|
+
inputs:
|
|
122
|
+
mode:
|
|
123
|
+
description: "Sync mode"
|
|
124
|
+
required: true
|
|
125
|
+
default: "since-ref"
|
|
126
|
+
type: choice
|
|
127
|
+
options:
|
|
128
|
+
- since-ref
|
|
129
|
+
- all
|
|
130
|
+
|
|
131
|
+
jobs:
|
|
132
|
+
sync:
|
|
133
|
+
uses: whiteout59/methodology-framework/.github/workflows/sync.yml@v0.1.0
|
|
134
|
+
with:
|
|
135
|
+
project_key: SCRUM
|
|
136
|
+
repo: whiteout59/centralized-pipeline-ui
|
|
137
|
+
story_path_pattern: "docs/stories/{phase1,phase2}/**/*.md"
|
|
138
|
+
cf_story_file: "customfield_10073"
|
|
139
|
+
cf_requirement_ids: "customfield_10141"
|
|
140
|
+
cf_agent_estimate: "customfield_10074"
|
|
141
|
+
mode: ${{ github.event.inputs.mode || 'since-ref' }}
|
|
142
|
+
jira_base_url: "https://myorg.atlassian.net"
|
|
143
|
+
jira_user_email: "devin-sync@myorg.atlassian.net"
|
|
144
|
+
secrets:
|
|
145
|
+
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The `mode` input defaults to `since-ref` for routine push-triggered
|
|
149
|
+
runs (preserves the 250-story scale guard). Pass `mode: all` explicitly
|
|
150
|
+
for nightly or `workflow_dispatch` full-corpus syncs.
|
|
151
|
+
|
|
152
|
+
> **Secrets forwarding:** the caller's `secrets:` block must explicitly
|
|
153
|
+
> map each secret the reusable workflow declares. Secrets are NOT
|
|
154
|
+
> inherited by default in reusable workflows. Using `secrets: inherit`
|
|
155
|
+
> works but is brittle — prefer explicit mapping.
|
|
156
|
+
|
|
157
|
+
### Playbook build + register workflow
|
|
158
|
+
|
|
159
|
+
Builds a concrete playbook from a parameterized body + bindings file,
|
|
160
|
+
then registers it with Devin's API. Create
|
|
161
|
+
`.github/workflows/build-and-register.yml` in the adopter repo:
|
|
162
|
+
|
|
163
|
+
```yaml
|
|
164
|
+
name: Build and register playbook
|
|
165
|
+
|
|
166
|
+
on:
|
|
167
|
+
push:
|
|
168
|
+
branches: [main]
|
|
169
|
+
paths:
|
|
170
|
+
- "methodology/playbooks/*.body.md"
|
|
171
|
+
- "docs/jira-pickup-config.md"
|
|
172
|
+
workflow_dispatch:
|
|
173
|
+
|
|
174
|
+
jobs:
|
|
175
|
+
build-and-register:
|
|
176
|
+
uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
|
|
177
|
+
with:
|
|
178
|
+
playbook_body_path: "methodology/playbooks/scrum-router.body.md"
|
|
179
|
+
bindings_path: "docs/jira-pickup-config.md"
|
|
180
|
+
secrets:
|
|
181
|
+
DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
> **Nesting limit:** GitHub allows reusable workflow nesting up to
|
|
185
|
+
> 4 levels deep. If your repo wraps these workflows in another
|
|
186
|
+
> caller layer, verify the total nesting depth stays within limits.
|
|
187
|
+
|
|
188
|
+
## PyPI Publishing
|
|
189
|
+
|
|
190
|
+
The package is published to PyPI automatically via OIDC Trusted Publishers
|
|
191
|
+
when a SemVer tag is pushed:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
git tag v0.1.0
|
|
195
|
+
git push origin v0.1.0
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The `pypi-release.yml` workflow builds and publishes using
|
|
199
|
+
`pypa/gh-action-pypi-publish` in OIDC mode -- no `PYPI_API_TOKEN` secret
|
|
200
|
+
is needed. The job uses the `pypi` GitHub environment for protection rules.
|
|
201
|
+
|
|
202
|
+
**Operator setup (one-time):** bind the PyPI project `methodology-framework`
|
|
203
|
+
to the GitHub repo `whiteout59/methodology-framework`, workflow
|
|
204
|
+
`pypi-release.yml`, environment `pypi` at
|
|
205
|
+
[PyPI Trusted Publishers](https://pypi.org/manage/account/publishing/).
|
|
206
|
+
|
|
207
|
+
## Cost tracking via `agent_acus`
|
|
208
|
+
|
|
209
|
+
The methodology's post-execution notes include an `agent_acus` field that
|
|
210
|
+
records per-story compute cost. Since agents cannot self-report ACU
|
|
211
|
+
consumption mid-session, a post-merge populator workflow backfills the
|
|
212
|
+
value from the Devin API after the session completes.
|
|
213
|
+
|
|
214
|
+
**Adopter wiring (3 steps):**
|
|
215
|
+
|
|
216
|
+
1. Copy the template caller into your repo:
|
|
217
|
+
```bash
|
|
218
|
+
cp "$(python -c "import methodology_framework; import pathlib; \
|
|
219
|
+
print(pathlib.Path(methodology_framework.__file__).parent / \
|
|
220
|
+
'templates/github_workflows/populate-story-acus-caller.yml')")" \
|
|
221
|
+
.github/workflows/populate-story-acus.yml
|
|
222
|
+
```
|
|
223
|
+
2. Set the `DEVIN_API_TOKEN` repo secret (Settings > Secrets and
|
|
224
|
+
variables > Actions > New repository secret).
|
|
225
|
+
3. Pin the framework version in the caller's `uses:` line.
|
|
226
|
+
|
|
227
|
+
The caller fires on merged PRs that touch story files, invokes the
|
|
228
|
+
reusable `populate-story-acus.yml` workflow, and opens a follow-on PR
|
|
229
|
+
with the populated ACU values.
|
|
230
|
+
|
|
231
|
+
## Development
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
pip install -e ".[dev]"
|
|
235
|
+
pytest tests/ -v
|
|
236
|
+
ruff check src/methodology_framework
|
|
237
|
+
ruff format --check src/methodology_framework
|
|
238
|
+
mypy --strict src/methodology_framework
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
## License
|
|
242
|
+
|
|
243
|
+
Apache-2.0
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=70.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "methodology-framework"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
requires-python = ">=3.12"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "whiteout59" },
|
|
14
|
+
]
|
|
15
|
+
dependencies = [
|
|
16
|
+
"requests>=2.31,<3",
|
|
17
|
+
"python-frontmatter>=1.1,<2",
|
|
18
|
+
"pyyaml>=6.0,<7",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
dev = [
|
|
23
|
+
"pytest>=8.0,<9",
|
|
24
|
+
"requests-mock>=1.12,<2",
|
|
25
|
+
"ruff==0.15.14",
|
|
26
|
+
"mypy>=1.10,<2",
|
|
27
|
+
"types-requests>=2.31,<3",
|
|
28
|
+
"types-PyYAML>=6.0,<7",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[tool.setuptools.packages.find]
|
|
32
|
+
where = ["src"]
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.package-data]
|
|
35
|
+
methodology_framework = [
|
|
36
|
+
"playbooks/*.md",
|
|
37
|
+
"templates/*.md",
|
|
38
|
+
"templates/github_workflows/*.yml",
|
|
39
|
+
"specs/*.md",
|
|
40
|
+
"jira_shapes/*.yaml",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[tool.ruff]
|
|
44
|
+
line-length = 99
|
|
45
|
+
target-version = "py312"
|
|
46
|
+
|
|
47
|
+
[tool.ruff.lint]
|
|
48
|
+
select = ["E", "F", "W", "I"]
|
|
49
|
+
|
|
50
|
+
[tool.mypy]
|
|
51
|
+
python_version = "3.12"
|
|
52
|
+
strict = true
|
|
53
|
+
warn_return_any = true
|
|
54
|
+
warn_unused_configs = true
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""methodology-framework — portable process tooling for agent-driven delivery."""
|
|
2
|
+
|
|
3
|
+
__version__ = "0.1.0"
|
|
4
|
+
|
|
5
|
+
from methodology_framework import (
|
|
6
|
+
bootstrap_jira,
|
|
7
|
+
build_playbook,
|
|
8
|
+
register_playbook_with_devin,
|
|
9
|
+
sync_stories_to_jira,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"bootstrap_jira",
|
|
14
|
+
"build_playbook",
|
|
15
|
+
"register_playbook_with_devin",
|
|
16
|
+
"sync_stories_to_jira",
|
|
17
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""Entry point for ``python -m methodology_framework <subcommand>``."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def main() -> None:
|
|
9
|
+
"""Route subcommands to their implementations."""
|
|
10
|
+
if len(sys.argv) < 2:
|
|
11
|
+
print("Usage: python -m methodology_framework <subcommand>", file=sys.stderr)
|
|
12
|
+
print("Available subcommands: bootstrap-jira", file=sys.stderr)
|
|
13
|
+
sys.exit(1)
|
|
14
|
+
|
|
15
|
+
subcommand = sys.argv[1]
|
|
16
|
+
|
|
17
|
+
if subcommand == "bootstrap-jira":
|
|
18
|
+
from methodology_framework.bootstrap_jira import main as bootstrap_main
|
|
19
|
+
|
|
20
|
+
sys.exit(bootstrap_main(sys.argv[2:]))
|
|
21
|
+
else:
|
|
22
|
+
print(f"Unknown subcommand: {subcommand}", file=sys.stderr)
|
|
23
|
+
print("Available subcommands: bootstrap-jira", file=sys.stderr)
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if __name__ == "__main__":
|
|
28
|
+
main()
|