Metadata-Version: 2.4
Name: methodology-framework
Version: 0.1.0
Summary: Portable process tooling for agent-driven delivery — scripts, playbooks, templates, and specs.
Author: whiteout59
License-Expression: Apache-2.0
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests<3,>=2.31
Requires-Dist: python-frontmatter<2,>=1.1
Requires-Dist: pyyaml<7,>=6.0
Provides-Extra: dev
Requires-Dist: pytest<9,>=8.0; extra == "dev"
Requires-Dist: requests-mock<2,>=1.12; extra == "dev"
Requires-Dist: ruff==0.15.14; extra == "dev"
Requires-Dist: mypy<2,>=1.10; extra == "dev"
Requires-Dist: types-requests<3,>=2.31; extra == "dev"
Requires-Dist: types-PyYAML<7,>=6.0; extra == "dev"
Dynamic: license-file

# methodology-framework

Portable process tooling for agent-driven delivery -- scripts, playbooks, templates, and specs.

## Installation

```bash
pip install -e .
```

## Package contents

- `methodology_framework.sync_stories_to_jira` -- one-way repo-to-Jira story sync
- `methodology_framework.build_playbook` -- build a concrete playbook from a parameterized body + bindings
- `methodology_framework.register_playbook_with_devin` -- register a rendered playbook with Devin's API
- `methodology_framework/playbooks/` -- parameterized playbook bodies (package data)
- `methodology_framework/templates/` -- story and process templates (package data)
- `methodology_framework/specs/` -- format specs (package data)
- `methodology_framework.bootstrap_jira` -- bootstrap a Jira project with the canonical workflow, custom fields, and automation rules
- `methodology_framework/jira_shapes/` -- canonical Jira shape definitions (YAML, package data)

## Jira Bootstrap

Adopting projects provision their Jira project shape from a single CLI command
instead of manually configuring 30+ admin UI screens.

### Prerequisites

- Python 3.12+
- `pip install methodology-framework` (or `pip install -e .` from source)
- For `--apply` mode: `JIRA_ADMIN_TOKEN` environment variable set to a Jira
  admin API token or OAuth Bearer token

### Usage

```bash
# Dry-run (default) — print what would be applied, no side-effects
python -m methodology_framework bootstrap-jira \
  --project-key=MYPROJ \
  --jira-host=myorg.atlassian.net \
  --dry-run

# Export — emit an importable config bundle (YAML); no API calls
python -m methodology_framework bootstrap-jira \
  --project-key=MYPROJ \
  --jira-host=myorg.atlassian.net \
  --export /tmp/jira-bundle.yaml

# Apply — provision the Jira project via admin API
export JIRA_ADMIN_TOKEN="<your-token>"
python -m methodology_framework bootstrap-jira \
  --project-key=MYPROJ \
  --jira-host=myorg.atlassian.net \
  --apply

# Apply with --force to skip confirmation prompts
python -m methodology_framework bootstrap-jira \
  --project-key=MYPROJ \
  --jira-host=myorg.atlassian.net \
  --apply --force
```

### Flags

| Flag | Required | Description |
|------|----------|-------------|
| `--project-key` | Yes | Jira project key (e.g. `SCRUM`). Substituted for `{{PROJECT_KEY}}` in shape defs. |
| `--jira-host` | Yes | Jira Cloud host (e.g. `myorg.atlassian.net`). No `https://` prefix. |
| `--dry-run` | No | Print what would be applied (default if no mode specified). |
| `--apply` | No | POST/PUT to Jira admin API. Requires `JIRA_ADMIN_TOKEN` env var. |
| `--export <path>` | No | Emit importable config bundle at `<path>`. |
| `--force` | No | Skip confirmation prompts during `--apply`. |

### Environment variables

| Variable | When needed | Description |
|----------|-------------|-------------|
| `JIRA_ADMIN_TOKEN` | `--apply` mode | Jira admin API token. **Never** accepted as a CLI flag. |

### Shape definitions

The three canonical shape files shipped as package data:

- `jira_shapes/workflow.yaml` — workflow statuses (To Do, Ready for AI agent,
  In Progress, In Review, Waiting, Blocked, Done, Won't do) and transitions
  with actor permissions
- `jira_shapes/custom_fields.yaml` — Story File (URL), Requirement IDs
  (labels), Agent Estimate (number)
- `jira_shapes/automation_rules.yaml` — PR-title-key auto-transition,
  dependency resolution, BLOCKED protection

For full methodology context see the methodology requirements doc § 4.13.3
("Jira Bootstrap CLI").

## Adopter Integration

Adopting projects consume the methodology framework's CI pipelines via
**reusable GitHub Actions workflows**. Instead of copying workflow YAML
into each repo, adopters write a thin caller that references the
framework's workflows by SemVer tag.

> **Version pinning requirement:** adopters MUST pin to a specific tag
> (`@v0.X.Y`), never `@main`. The framework version must be explicit
> in the caller so updates are deliberate, not silent. This matches the
> version-pinning model per methodology requirements § 4.13.

### Story sync workflow

Syncs story `.md` files from the adopter's repo to Jira. Create
`.github/workflows/sync.yml` in the adopter repo:

```yaml
name: Sync stories to Jira

on:
  push:
    branches: [main]
    paths:
      - "docs/stories/**/*.md"
  workflow_dispatch:
    inputs:
      mode:
        description: "Sync mode"
        required: true
        default: "since-ref"
        type: choice
        options:
          - since-ref
          - all

jobs:
  sync:
    uses: whiteout59/methodology-framework/.github/workflows/sync.yml@v0.1.0
    with:
      project_key: SCRUM
      repo: whiteout59/centralized-pipeline-ui
      story_path_pattern: "docs/stories/{phase1,phase2}/**/*.md"
      cf_story_file: "customfield_10073"
      cf_requirement_ids: "customfield_10141"
      cf_agent_estimate: "customfield_10074"
      mode: ${{ github.event.inputs.mode || 'since-ref' }}
      jira_base_url: "https://myorg.atlassian.net"
      jira_user_email: "devin-sync@myorg.atlassian.net"
    secrets:
      JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
```

The `mode` input defaults to `since-ref` for routine push-triggered
runs (preserves the 250-story scale guard). Pass `mode: all` explicitly
for nightly or `workflow_dispatch` full-corpus syncs.

> **Secrets forwarding:** the caller's `secrets:` block must explicitly
> map each secret the reusable workflow declares. Secrets are NOT
> inherited by default in reusable workflows. Using `secrets: inherit`
> works but is brittle — prefer explicit mapping.

### Playbook build + register workflow

Builds a concrete playbook from a parameterized body + bindings file,
then registers it with Devin's API. Create
`.github/workflows/build-and-register.yml` in the adopter repo:

```yaml
name: Build and register playbook

on:
  push:
    branches: [main]
    paths:
      - "methodology/playbooks/*.body.md"
      - "docs/jira-pickup-config.md"
  workflow_dispatch:

jobs:
  build-and-register:
    uses: whiteout59/methodology-framework/.github/workflows/build-and-register.yml@v0.1.0
    with:
      playbook_body_path: "methodology/playbooks/scrum-router.body.md"
      bindings_path: "docs/jira-pickup-config.md"
    secrets:
      DEVIN_API_TOKEN: ${{ secrets.DEVIN_API_TOKEN }}
```

> **Nesting limit:** GitHub allows reusable workflow nesting up to
> 4 levels deep. If your repo wraps these workflows in another
> caller layer, verify the total nesting depth stays within limits.

## PyPI Publishing

The package is published to PyPI automatically via OIDC Trusted Publishers
when a SemVer tag is pushed:

```bash
git tag v0.1.0
git push origin v0.1.0
```

The `pypi-release.yml` workflow builds and publishes using
`pypa/gh-action-pypi-publish` in OIDC mode -- no `PYPI_API_TOKEN` secret
is needed. The job uses the `pypi` GitHub environment for protection rules.

**Operator setup (one-time):** bind the PyPI project `methodology-framework`
to the GitHub repo `whiteout59/methodology-framework`, workflow
`pypi-release.yml`, environment `pypi` at
[PyPI Trusted Publishers](https://pypi.org/manage/account/publishing/).

## Cost tracking via `agent_acus`

The methodology's post-execution notes include an `agent_acus` field that
records per-story compute cost. Since agents cannot self-report ACU
consumption mid-session, a post-merge populator workflow backfills the
value from the Devin API after the session completes.

**Adopter wiring (3 steps):**

1. Copy the template caller into your repo:
   ```bash
   cp "$(python -c "import methodology_framework; import pathlib; \
     print(pathlib.Path(methodology_framework.__file__).parent / \
     'templates/github_workflows/populate-story-acus-caller.yml')")" \
     .github/workflows/populate-story-acus.yml
   ```
2. Set the `DEVIN_API_TOKEN` repo secret (Settings > Secrets and
   variables > Actions > New repository secret).
3. Pin the framework version in the caller's `uses:` line.

The caller fires on merged PRs that touch story files, invokes the
reusable `populate-story-acus.yml` workflow, and opens a follow-on PR
with the populated ACU values.

## Development

```bash
pip install -e ".[dev]"
pytest tests/ -v
ruff check src/methodology_framework
ruff format --check src/methodology_framework
mypy --strict src/methodology_framework
```

## License

Apache-2.0
