methodology-framework 0.4.2__tar.gz → 0.4.3__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.4.2/src/methodology_framework.egg-info → methodology_framework-0.4.3}/PKG-INFO +2 -2
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/README.md +1 -1
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/pyproject.toml +1 -1
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/build_playbook.py +3 -3
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/jira_discovery.py +86 -21
- methodology_framework-0.4.2/src/methodology_framework/playbooks/scrum-router.body.md → methodology_framework-0.4.3/src/methodology_framework/playbooks/router-base.body.md +2 -1
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/register_playbook_with_devin.py +1 -3
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/sync_stories_to_jira.py +6 -3
- {methodology_framework-0.4.2 → methodology_framework-0.4.3/src/methodology_framework.egg-info}/PKG-INFO +2 -2
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework.egg-info/SOURCES.txt +1 -1
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/LICENSE +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/setup.cfg +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/__init__.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/__main__.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/bootstrap_jira.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/jira_shapes/__init__.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/jira_shapes/automation_rules.yaml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/jira_shapes/custom_fields.yaml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/jira_shapes/workflow.yaml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/playbooks/bindings/meth.yaml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/playbooks/bindings/scrum.yaml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/populate_acus.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/specs/devin-story-format.md +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/templates/github_workflows/populate-story-acus-caller.yml +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/templates/story.md +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework.egg-info/dependency_links.txt +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework.egg-info/requires.txt +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework.egg-info/top_level.txt +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_bootstrap_jira.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_build_playbook.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_jira_discovery.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_populate_acus.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_populate_acus_integration.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_register_playbook_with_devin.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_sync_stories_to_jira.py +0 -0
- {methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_workflows.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: methodology-framework
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs.
|
|
5
5
|
Author: whiteout59
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -316,7 +316,7 @@ jobs:
|
|
|
316
316
|
build-and-register:
|
|
317
317
|
uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
|
|
318
318
|
with:
|
|
319
|
-
playbook_body_path: "methodology/playbooks/
|
|
319
|
+
playbook_body_path: "methodology/playbooks/router-base.body.md"
|
|
320
320
|
bindings_path: "docs/jira-pickup-config.md"
|
|
321
321
|
secrets:
|
|
322
322
|
DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
|
|
@@ -292,7 +292,7 @@ jobs:
|
|
|
292
292
|
build-and-register:
|
|
293
293
|
uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
|
|
294
294
|
with:
|
|
295
|
-
playbook_body_path: "methodology/playbooks/
|
|
295
|
+
playbook_body_path: "methodology/playbooks/router-base.body.md"
|
|
296
296
|
bindings_path: "docs/jira-pickup-config.md"
|
|
297
297
|
secrets:
|
|
298
298
|
DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "methodology-framework"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.3"
|
|
8
8
|
description = "Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "Apache-2.0"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
"""Build a concrete, project-bound playbook from the parameterized body + bindings.
|
|
3
3
|
|
|
4
|
-
Reads the parameterized playbook body from methodology/playbooks/
|
|
4
|
+
Reads the parameterized playbook body from methodology/playbooks/router-base.body.md
|
|
5
5
|
and substitutes {{PLACEHOLDER}} tokens with the project-specific bindings defined in
|
|
6
6
|
docs/jira-pickup-config.md § 5.1 (the playbook_bindings YAML block).
|
|
7
7
|
|
|
@@ -23,7 +23,7 @@ Options:
|
|
|
23
23
|
Does not write output.
|
|
24
24
|
|
|
25
25
|
When --body and --bindings are omitted, the script falls back to the legacy
|
|
26
|
-
hardcoded paths (methodology/playbooks/
|
|
26
|
+
hardcoded paths (methodology/playbooks/router-base.body.md and
|
|
27
27
|
docs/jira-pickup-config.md relative to the repo root).
|
|
28
28
|
"""
|
|
29
29
|
|
|
@@ -35,7 +35,7 @@ import sys
|
|
|
35
35
|
from pathlib import Path
|
|
36
36
|
|
|
37
37
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
38
|
-
BODY_PATH = REPO_ROOT / "methodology" / "playbooks" / "
|
|
38
|
+
BODY_PATH = REPO_ROOT / "methodology" / "playbooks" / "router-base.body.md"
|
|
39
39
|
CONFIG_PATH = REPO_ROOT / "docs" / "jira-pickup-config.md"
|
|
40
40
|
|
|
41
41
|
PLACEHOLDER_RE = re.compile(r"\{\{(\w+)\}\}")
|
|
@@ -229,24 +229,14 @@ def discover_statuses(
|
|
|
229
229
|
return result
|
|
230
230
|
|
|
231
231
|
|
|
232
|
-
def
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
type, then queries the workflow scheme. Falls back to scanning
|
|
241
|
-
transitions from each status via the workflow spec.
|
|
242
|
-
|
|
243
|
-
For transitions, the approach is: use the statuses endpoint to get
|
|
244
|
-
status names, then use GET /rest/api/3/status to get transitions.
|
|
245
|
-
But Jira Cloud doesn't expose transitions without an issue context.
|
|
246
|
-
|
|
247
|
-
Instead, we create a name→ID map from the workflow spec (which has
|
|
248
|
-
transition_id values) and verify they're consistent with what's live.
|
|
249
|
-
The verifier already checked these exist; we trust the spec IDs.
|
|
232
|
+
def _spec_transition_map() -> dict[str, str]:
|
|
233
|
+
"""Return canonical transition name→ID map sourced from workflow.yaml.
|
|
234
|
+
|
|
235
|
+
Used only for dry-run sync invocations where no Jira credentials are
|
|
236
|
+
available. Returns the SCRUM-accidental IDs encoded in the spec —
|
|
237
|
+
these are stable for the SCRUM project but will NOT match a freshly-
|
|
238
|
+
provisioned team-managed project. Real sync uses :func:`discover_transitions`
|
|
239
|
+
which queries Jira directly.
|
|
250
240
|
"""
|
|
251
241
|
shape = _load_shape(_WORKFLOW_YAML)
|
|
252
242
|
result: dict[str, str] = {}
|
|
@@ -256,11 +246,86 @@ def discover_transitions(
|
|
|
256
246
|
tid = str(t["transition_id"])
|
|
257
247
|
if name not in result:
|
|
258
248
|
result[name] = tid
|
|
249
|
+
return result
|
|
259
250
|
|
|
260
|
-
if not result:
|
|
261
|
-
raise _fail("transition", "(any)", project_key)
|
|
262
251
|
|
|
263
|
-
|
|
252
|
+
def discover_transitions(
|
|
253
|
+
session: Any,
|
|
254
|
+
base_url: str,
|
|
255
|
+
project_key: str,
|
|
256
|
+
) -> dict[str, str]:
|
|
257
|
+
"""Discover transition name→ID map by querying Jira directly.
|
|
258
|
+
|
|
259
|
+
Strategy: find any existing issue in the project via JQL search, then
|
|
260
|
+
call ``GET /rest/api/3/issue/{key}/transitions`` to read the live
|
|
261
|
+
transition map for the workflow. The framework's canonical workflow
|
|
262
|
+
uses global transitions (``isGlobal: true``), so any single issue
|
|
263
|
+
exposes the complete name→ID map.
|
|
264
|
+
|
|
265
|
+
Raises :class:`DiscoveryError` if:
|
|
266
|
+
|
|
267
|
+
- The project has no issues yet (operator must create at least one
|
|
268
|
+
issue before first sync — sync can't probe an empty project's
|
|
269
|
+
workflow because Jira Cloud only exposes transitions in an issue
|
|
270
|
+
context).
|
|
271
|
+
- Any canonical transition name is missing from the live workflow
|
|
272
|
+
(operator must fix the workflow per ``bootstrap-jira --verify``).
|
|
273
|
+
|
|
274
|
+
For SCRUM the discovered IDs match :func:`_spec_transition_map` by
|
|
275
|
+
historical accident. For freshly-provisioned projects they will not —
|
|
276
|
+
that's the point of querying instead of trusting the spec.
|
|
277
|
+
"""
|
|
278
|
+
# Find any existing issue in the project via JQL.
|
|
279
|
+
resp = session.get(
|
|
280
|
+
f"{base_url}/rest/api/3/search/jql",
|
|
281
|
+
params={
|
|
282
|
+
"jql": f"project={project_key}",
|
|
283
|
+
"fields": "key",
|
|
284
|
+
"maxResults": 1,
|
|
285
|
+
},
|
|
286
|
+
)
|
|
287
|
+
resp.raise_for_status()
|
|
288
|
+
search_data: dict[str, Any] = resp.json()
|
|
289
|
+
issues = search_data.get("issues") or []
|
|
290
|
+
|
|
291
|
+
if not issues:
|
|
292
|
+
raise DiscoveryError(
|
|
293
|
+
f"Project {project_key} has no issues yet, so workflow transitions "
|
|
294
|
+
f"cannot be probed. Jira Cloud only exposes transition IDs in an "
|
|
295
|
+
f"issue context. Create at least one placeholder issue in "
|
|
296
|
+
f"{project_key} (any issue type, any state) and re-run sync. "
|
|
297
|
+
f"That issue is enough — discovery uses it as a probe to read the "
|
|
298
|
+
f"global transition map for the project's workflow."
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
probe_key: str = issues[0]["key"]
|
|
302
|
+
logger.info(
|
|
303
|
+
"Probing transitions on %s (any existing issue exposes the global "
|
|
304
|
+
"transition map for the project's workflow).",
|
|
305
|
+
probe_key,
|
|
306
|
+
)
|
|
307
|
+
|
|
308
|
+
resp = session.get(f"{base_url}/rest/api/3/issue/{probe_key}/transitions")
|
|
309
|
+
resp.raise_for_status()
|
|
310
|
+
transitions_data: dict[str, Any] = resp.json()
|
|
311
|
+
|
|
312
|
+
name_to_id: dict[str, str] = {}
|
|
313
|
+
for t in transitions_data.get("transitions", []):
|
|
314
|
+
name_to_id[t["name"]] = str(t["id"])
|
|
315
|
+
|
|
316
|
+
# Verify every canonical transition name resolved.
|
|
317
|
+
canonical = _canonical_transition_names()
|
|
318
|
+
missing = canonical - set(name_to_id.keys())
|
|
319
|
+
if missing:
|
|
320
|
+
raise DiscoveryError(
|
|
321
|
+
f"Project {project_key}'s workflow is missing required transition(s): "
|
|
322
|
+
f"{', '.join(sorted(missing))}. "
|
|
323
|
+
f"Run 'methodology-framework bootstrap-jira --verify "
|
|
324
|
+
f"--project-key={project_key}' to identify the gaps, then add the "
|
|
325
|
+
f"missing states/transitions in the Jira workflow editor."
|
|
326
|
+
)
|
|
327
|
+
|
|
328
|
+
return name_to_id
|
|
264
329
|
|
|
265
330
|
|
|
266
331
|
def discover_link_types(
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
playbook_id: {{PLAYBOOK_ID}}
|
|
3
|
-
version: 1.
|
|
3
|
+
version: 1.6.0
|
|
4
4
|
changelog:
|
|
5
|
+
- "1.6.0 (2026-06-07): Renamed body file from `scrum-router.body.md` to `router-base.body.md`. Canonical-template naming should be project-neutral; the SCRUM prefix was a legacy artifact from when the playbook had a single SCRUM binding. The rendered outputs continue to be named per-binding via `{{PLAYBOOK_ID}}` (scrum-router, meth-router, etc.). Code + workflow references updated to the new path. Closes #113. MINOR bump per SemVer (additive: file rename + reference updates, no body content change)."
|
|
5
6
|
- "1.5.0 (2026-06-07): Parameterize all self-references via new {{PLAYBOOK_ID}} substitution token (previously hardcoded as `scrum-router` in 4 places — frontmatter, the audit-banner step, the comment template, and the webapp settings-path reference). Bindings (scrum.yaml, meth.yaml) now declare PLAYBOOK_ID. Rendered METH playbook now correctly emits `meth-router` in the audit banner instead of `scrum-router` (surfaced by the post-extraction smoke #71 / METH-5). MINOR bump per SemVer (new substitution token added; no breaking change since all bindings updated simultaneously). Closes #92."
|
|
6
7
|
- "1.4.0 (2026-06-02): Added METH as a second bound project alongside SCRUM. Surface expansion only; no body changes. MINOR bump per SemVer (binding surface expands without breaking existing callers)."
|
|
7
8
|
- "1.3.0 (2026-05-29): New convention — cross-repo writeback discipline (story file in repo A, implementation in repo B → two-PR pattern with writeback PR in repo A). New convention — agent populates agent_session_url field in post-execution notes block. New convention — agent_acus field added to post-exec block (default \"pending\"; populated asynchronously by post-merge automation since agents cannot self-report ACU consumption mid-session). MINOR bump per SemVer (three additive new conventions, no breaking changes for single-repo work)."
|
|
@@ -103,9 +103,7 @@ def list_playbooks(token: str, org_id: str) -> list[dict[str, Any]]:
|
|
|
103
103
|
# forward-compat across API shape changes.
|
|
104
104
|
if isinstance(resp, list):
|
|
105
105
|
return resp
|
|
106
|
-
items: list[dict[str, Any]] = resp.get(
|
|
107
|
-
"items", resp.get("playbooks", resp.get("data", []))
|
|
108
|
-
)
|
|
106
|
+
items: list[dict[str, Any]] = resp.get("items", resp.get("playbooks", resp.get("data", [])))
|
|
109
107
|
return items
|
|
110
108
|
|
|
111
109
|
|
|
@@ -1070,10 +1070,13 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
1070
1070
|
logger.error("Jira shape discovery failed: %s", exc)
|
|
1071
1071
|
return 1
|
|
1072
1072
|
else:
|
|
1073
|
-
# In dry-run mode, use a placeholder shape with spec-sourced IDs
|
|
1074
|
-
|
|
1073
|
+
# In dry-run mode, use a placeholder shape with spec-sourced IDs.
|
|
1074
|
+
# _spec_transition_map() reads workflow.yaml and never calls Jira —
|
|
1075
|
+
# safe for dry-run where credentials may be absent. Real sync uses
|
|
1076
|
+
# discover_transitions() which probes a live issue.
|
|
1077
|
+
from methodology_framework.jira_discovery import _spec_transition_map
|
|
1075
1078
|
|
|
1076
|
-
transitions =
|
|
1079
|
+
transitions = _spec_transition_map()
|
|
1077
1080
|
shape = JiraShape(
|
|
1078
1081
|
project_key=project_key,
|
|
1079
1082
|
cf_story_file="DRY_RUN_CF",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: methodology-framework
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.3
|
|
4
4
|
Summary: Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs.
|
|
5
5
|
Author: whiteout59
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -316,7 +316,7 @@ jobs:
|
|
|
316
316
|
build-and-register:
|
|
317
317
|
uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
|
|
318
318
|
with:
|
|
319
|
-
playbook_body_path: "methodology/playbooks/
|
|
319
|
+
playbook_body_path: "methodology/playbooks/router-base.body.md"
|
|
320
320
|
bindings_path: "docs/jira-pickup-config.md"
|
|
321
321
|
secrets:
|
|
322
322
|
DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
|
|
@@ -18,7 +18,7 @@ src/methodology_framework/jira_shapes/__init__.py
|
|
|
18
18
|
src/methodology_framework/jira_shapes/automation_rules.yaml
|
|
19
19
|
src/methodology_framework/jira_shapes/custom_fields.yaml
|
|
20
20
|
src/methodology_framework/jira_shapes/workflow.yaml
|
|
21
|
-
src/methodology_framework/playbooks/
|
|
21
|
+
src/methodology_framework/playbooks/router-base.body.md
|
|
22
22
|
src/methodology_framework/playbooks/bindings/meth.yaml
|
|
23
23
|
src/methodology_framework/playbooks/bindings/scrum.yaml
|
|
24
24
|
src/methodology_framework/specs/devin-story-format.md
|
|
File without changes
|
|
File without changes
|
{methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/__init__.py
RENAMED
|
File without changes
|
{methodology_framework-0.4.2 → methodology_framework-0.4.3}/src/methodology_framework/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_populate_acus_integration.py
RENAMED
|
File without changes
|
|
File without changes
|
{methodology_framework-0.4.2 → methodology_framework-0.4.3}/tests/test_sync_stories_to_jira.py
RENAMED
|
File without changes
|
|
File without changes
|