Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# CODEOWNERS - Define code ownership and required reviewers
# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners

# Default owner for everything
* @itdove

# Critical workflow files - require owner approval
/.github/workflows/publish.yml @itdove
/.github/workflows/publish-test.yml @itdove
/.github/workflows/tag-monitor.yml @itdove

# Release documentation - require owner approval
/RELEASING.md @itdove
/CONTRIBUTING.md @itdove

# Security and configuration
/.github/CODEOWNERS @itdove
/.gitignore @itdove

# Version files - require owner approval
/pyproject.toml @itdove
/devflow/__init__.py @itdove

# Release management module
/devflow/release/ @itdove

# CLI commands that affect releases
/devflow/cli/commands/release_command.py @itdove
152 changes: 152 additions & 0 deletions .github/workflows/tag-monitor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
name: Tag Creation Monitor

on:
push:
tags:
- 'v*' # Production tags (v1.0.0, v2.2.0)
- 'v*-test*' # Test tags (v1.0.0-test1, v2.2.0-test1)

jobs:
monitor-and-notify:
runs-on: ubuntu-latest
permissions:
contents: read
issues: write

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Get tag information
id: tag-info
run: |
TAG_NAME="${GITHUB_REF#refs/tags/}"
TAG_CREATOR="${GITHUB_ACTOR}"
TAG_COMMIT=$(git rev-list -n 1 "${TAG_NAME}")
COMMIT_AUTHOR=$(git log -1 --pretty=%an "${TAG_COMMIT}")

echo "tag_name=${TAG_NAME}" >> $GITHUB_OUTPUT
echo "tag_creator=${TAG_CREATOR}" >> $GITHUB_OUTPUT
echo "tag_commit=${TAG_COMMIT}" >> $GITHUB_OUTPUT
echo "commit_author=${COMMIT_AUTHOR}" >> $GITHUB_OUTPUT

- name: Check authorization
id: auth-check
run: |
TAG_NAME="${{ steps.tag-info.outputs.tag_name }}"
TAG_CREATOR="${{ steps.tag-info.outputs.tag_creator }}"

# Authorized maintainers who can create production releases
AUTHORIZED_USERS=("itdove")

# Check if production release
if [[ "${TAG_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
IS_PRODUCTION="true"
TAG_TYPE="Production Release"
elif [[ "${TAG_NAME}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+-test ]]; then
IS_PRODUCTION="false"
TAG_TYPE="Test Release"
else
IS_PRODUCTION="false"
TAG_TYPE="Unknown"
fi

# Check authorization
IS_AUTHORIZED="false"
if [ "${IS_PRODUCTION}" = "true" ]; then
for user in "${AUTHORIZED_USERS[@]}"; do
if [ "${TAG_CREATOR}" = "${user}" ]; then
IS_AUTHORIZED="true"
break
fi
done
else
# Test releases are allowed for everyone
IS_AUTHORIZED="true"
fi

echo "is_production=${IS_PRODUCTION}" >> $GITHUB_OUTPUT
echo "tag_type=${TAG_TYPE}" >> $GITHUB_OUTPUT
echo "is_authorized=${IS_AUTHORIZED}" >> $GITHUB_OUTPUT

echo "Tag Type: ${TAG_TYPE}"
echo "Created by: ${TAG_CREATOR}"
echo "Authorized: ${IS_AUTHORIZED}"

- name: Log tag creation (authorized)
if: steps.auth-check.outputs.is_authorized == 'true'
run: |
echo "::notice title=Authorized Tag Created::Tag '${{ steps.tag-info.outputs.tag_name }}' created by @${{ steps.tag-info.outputs.tag_creator }}"
echo ""
echo "========================================================================"
echo "✓ AUTHORIZED TAG CREATION"
echo "========================================================================"
echo "Tag: ${{ steps.tag-info.outputs.tag_name }}"
echo "Type: ${{ steps.auth-check.outputs.tag_type }}"
echo "Created by: @${{ steps.tag-info.outputs.tag_creator }}"
echo "Commit: ${{ steps.tag-info.outputs.tag_commit }}"
echo "Authorization: ✓ Authorized"
echo "========================================================================"

- name: Log tag creation (unauthorized)
if: steps.auth-check.outputs.is_authorized == 'false'
run: |
echo "::error title=Unauthorized Tag::Production tag '${{ steps.tag-info.outputs.tag_name }}' created by unauthorized user @${{ steps.tag-info.outputs.tag_creator }}"
echo ""
echo "========================================================================"
echo "✗ UNAUTHORIZED TAG CREATION"
echo "========================================================================"
echo "Tag: ${{ steps.tag-info.outputs.tag_name }}"
echo "Type: ${{ steps.auth-check.outputs.tag_type }}"
echo "Created by: @${{ steps.tag-info.outputs.tag_creator }}"
echo "Authorization: ✗ NOT AUTHORIZED"
echo ""
echo "ACTION REQUIRED:"
echo "1. Delete tag: git push origin :refs/tags/${{ steps.tag-info.outputs.tag_name }}"
echo "2. Report to repository owner"
echo "========================================================================"
exit 1

- name: Create security issue (unauthorized)
if: steps.auth-check.outputs.is_authorized == 'false'
uses: actions/github-script@v7
with:
script: |
const tagName = '${{ steps.tag-info.outputs.tag_name }}';
const tagCreator = '${{ steps.tag-info.outputs.tag_creator }}';
const commitSha = '${{ steps.tag-info.outputs.tag_commit }}';

const issueBody = [
'## Unauthorized Release Tag Detected',
'',
`**Tag:** \`${tagName}\``,
`**Created by:** @${tagCreator}`,
`**Commit:** ${commitSha}`,
`**Time:** ${new Date().toISOString()}`,
'',
'## Required Actions',
'',
'- [ ] Verify if intentional',
`- [ ] Delete tag: \`git push origin :refs/tags/${tagName}\``,
`- [ ] Review RELEASING.md policy with @${tagCreator}`,
'- [ ] Recreate by authorized user if needed',
'',
'## Fork-Based Workflow',
'',
'This repository uses a fork-based workflow for contributions:',
'- **Contributors** must fork and submit PRs',
'- **Maintainers** (@itdove) create releases',
'- See [CONTRIBUTING.md](CONTRIBUTING.md) and [RELEASING.md](RELEASING.md)',
'',
'_Auto-generated by tag-monitor workflow_'
].join('\n');

await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `🚨 Unauthorized Release Tag: ${tagName}`,
labels: ['security', 'unauthorized-release', 'priority-high'],
body: issueBody
});
19 changes: 15 additions & 4 deletions .wolf/anatomy.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# anatomy.md

> Auto-maintained by OpenWolf. Last scanned: 2026-04-08T02:00:17.107Z
> Files: 506 tracked | Anatomy hits: 0 | Misses: 0
> Auto-maintained by OpenWolf. Last scanned: 2026-04-08T14:20:27.349Z
> Files: 511 tracked | Anatomy hits: 0 | Misses: 0

## ../../../.claude/skills/release/

- `release_helper.py` — ReleaseHelper: get_current_version, update_version, calculate_next_version, update_changelog + 2 mor (~3826 tok)
- `SKILL.md` — DevAIFlow Release Skill (~2689 tok)

## ./

Expand All @@ -11,14 +16,15 @@
- `CHANGELOG.md` — Change log (~4649 tok)
- `CLAUDE.md` — OpenWolf (~139 tok)
- `config.schema.json` (~9891 tok)
- `CONTRIBUTING.md` — Contributing to DevAIFlow (~2458 tok)
- `CONTRIBUTING.md` — Contributing to DevAIFlow (~2695 tok)
- `coverage.json` (~12790 tok)
- `demo_branch_selection.sh` — Demo script showing the new branch source selection feature (~846 tok)
- `FORK_WORKFLOW_SETUP.md` — Fork-Based Workflow Setup Guide (~1503 tok)
- `LICENSE` — Project license (~3029 tok)
- `pyproject.toml` — Python project configuration (~702 tok)
- `QUICKREF.md` — DevAIFlow Quick Reference (~1384 tok)
- `README.md` — Project documentation (~6603 tok)
- `RELEASING.md` — Release Management Process (~3523 tok)
- `RELEASING.md` — Release Management Process (~3825 tok)
- `requirements-dev.txt` (~28 tok)
- `requirements.txt` — Python dependencies (~72 tok)
- `SECURITY.md` — Security Policy (~1380 tok)
Expand All @@ -34,6 +40,10 @@

- `openwolf.md` (~313 tok)

## .github/

- `CODEOWNERS` — CODEOWNERS - Define code ownership and required reviewers (~222 tok)

## .github/ISSUE_TEMPLATE/

- `agent-validation.md` — Environment (~360 tok)
Expand All @@ -44,6 +54,7 @@
- `lint.yml` — GitHub Actions CI/CD - Lint Workflow (~534 tok)
- `publish-test.yml` — GitHub Actions CI/CD - TestPyPI Publish Workflow (~370 tok)
- `publish.yml` — GitHub Actions CI/CD - PyPI Publish Workflow (~582 tok)
- `tag-monitor.yml` — CI: Tag Creation Monitor (~1799 tok)
- `test.yml` — GitHub Actions CI/CD - Test Workflow (~467 tok)

## .pytest_cache/
Expand Down
32 changes: 32 additions & 0 deletions .wolf/buglog.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,38 @@
"related_bugs": [],
"occurrences": 1,
"last_seen": "2026-04-08T01:53:30.693Z"
},
{
"id": "bug-004",
"timestamp": "2026-04-08T14:13:53.762Z",
"error_message": "Significant refactor of ",
"file": ".github/workflows/tag-monitor.yml",
"root_cause": "16 lines replaced/restructured",
"fix": "Rewrote 37→41 lines (16 removed)",
"tags": [
"auto-detected",
"refactor",
"yml"
],
"related_bugs": [],
"occurrences": 1,
"last_seen": "2026-04-08T14:13:53.762Z"
},
{
"id": "bug-005",
"timestamp": "2026-04-08T14:19:28.337Z",
"error_message": "Significant refactor of ",
"file": "FORK_WORKFLOW_SETUP.md",
"root_cause": "2 lines replaced/restructured",
"fix": "Rewrote 14→25 lines (2 removed) | Also: ### 1. Remove Write Access from Non-Maintainers; **Goal**: Force contributors to use forks by remov | Also: ### 2. Enable Branch Protection Rules; **Goal**: Prevent direct pushes to main branch, re",
"tags": [
"auto-detected",
"refactor",
"md"
],
"related_bugs": [],
"occurrences": 3,
"last_seen": "2026-04-08T14:20:08.541Z"
}
]
}
6 changes: 3 additions & 3 deletions .wolf/cron-state.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"last_heartbeat": null,
"engine_status": "initialized",
"last_heartbeat": "2026-04-08T14:17:46.043Z",
"engine_status": "running",
"execution_log": [],
"dead_letter_queue": [],
"upcoming": []
}
}
4 changes: 2 additions & 2 deletions .wolf/hooks/_session.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"session_id": "session-2026-04-08-2200",
"started": "2026-04-08T02:00:56.461Z",
"session_id": "session-2026-04-08-1023",
"started": "2026-04-08T14:23:00.781Z",
"files_read": {},
"files_written": [],
"edit_counts": {},
Expand Down
64 changes: 64 additions & 0 deletions .wolf/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,67 @@

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|

## Session: 2026-04-08 22:01

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|

## Session: 2026-04-08 08:08

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|

## Session: 2026-04-08 09:16

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|

## Session: 2026-04-08 09:17

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|

## Session: 2026-04-08 09:29

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|
| 09:49 | Created ../../../.claude/skills/release/SKILL.md | — | ~2868 |
| 09:49 | Edited ../../../.claude/skills/release/release_helper.py | 10→10 lines | ~87 |
| 09:49 | Edited ../../../.claude/skills/release/release_helper.py | modified __init__() | ~120 |
| 09:49 | Edited ../../../.claude/skills/release/release_helper.py | modified _read_version_from_init() | ~124 |
| 09:49 | Edited ../../../.claude/skills/release/release_helper.py | modified exists() | ~95 |
| 09:49 | Edited ../../../.claude/skills/release/release_helper.py | modified main() | ~73 |
| 09:50 | Created .github/workflows/tag-monitor.yml | — | ~1673 |
| 09:50 | Created .github/CODEOWNERS | — | ~222 |
| 09:56 | Edited CONTRIBUTING.md | expanded (+36 lines) | ~379 |
| 10:09 | Edited RELEASING.md | expanded (+54 lines) | ~527 |
| 10:10 | Edited .github/workflows/tag-monitor.yml | 7→7 lines | ~81 |
| 10:13 | Edited .github/workflows/tag-monitor.yml | 37→41 lines | ~516 |
| 10:15 | Implemented fork-based workflow and release automation (issue #369) | SKILL.md, release_helper.py, tag-monitor.yml, CODEOWNERS, CONTRIBUTING.md, RELEASING.md | Complete implementation | ~3000 |
| 10:15 | Updated ~/.claude/skills/release/ skill for DevAIFlow | SKILL.md, release_helper.py | Changed from ai-guardian to devaiflow paths | ~500 |
| 10:15 | Created tag monitoring workflow | .github/workflows/tag-monitor.yml | Monitors unauthorized releases | ~1700 |
| 10:15 | Created CODEOWNERS file | .github/CODEOWNERS | Protects critical release files | ~220 |
| 10:15 | Updated fork-based workflow documentation | CONTRIBUTING.md, RELEASING.md | Added authorization policies | ~900 |
| 10:14 | Session end: 12 writes across 6 files (SKILL.md, release_helper.py, tag-monitor.yml, CODEOWNERS, CONTRIBUTING.md) | 9 reads | ~51619 tok |
| 10:16 | Created FORK_WORKFLOW_SETUP.md | — | ~1827 |
| 10:17 | Session end: 13 writes across 7 files (SKILL.md, release_helper.py, tag-monitor.yml, CODEOWNERS, CONTRIBUTING.md) | 9 reads | ~53576 tok |
| 10:19 | Edited FORK_WORKFLOW_SETUP.md | expanded (+11 lines) | ~219 |
| 10:20 | Edited FORK_WORKFLOW_SETUP.md | maintainers() → itdove() | ~81 |
| 10:20 | Edited FORK_WORKFLOW_SETUP.md | reduced (-14 lines) | ~101 |
| 10:20 | Edited FORK_WORKFLOW_SETUP.md | reduced (-6 lines) | ~175 |
| 10:20 | Edited FORK_WORKFLOW_SETUP.md | 16→17 lines | ~152 |
| 10:18 | Enabled tag protection for v* tags | GitHub repository settings | Ruleset created via API | ~100 |
| 10:19 | Updated FORK_WORKFLOW_SETUP.md with completed status | FORK_WORKFLOW_SETUP.md | All protections now in place | ~300 |
| 10:21 | Session end: 18 writes across 7 files (SKILL.md, release_helper.py, tag-monitor.yml, CODEOWNERS, CONTRIBUTING.md) | 9 reads | ~54356 tok |

## Session: 2026-04-08 10:22

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|
| 10:22 | Deleted FORK_WORKFLOW_SETUP.md | — | Setup completed, guide no longer needed | ~50 |

## Session: 2026-04-08 10:23

| Time | Action | File(s) | Outcome | ~Tokens |
|------|--------|---------|---------|--------|
Loading
Loading