Metadata-Version: 2.4
Name: sdlc-framework
Version: 0.6.3
Summary: Local-only multi-AI SDLC framework with auto-detect engine, tier-aware DoD, and GitHub integration
Project-URL: Homepage, https://github.com/vuonglq01685/SDLC
Project-URL: Source, https://github.com/vuonglq01685/SDLC
Project-URL: Issues, https://github.com/vuonglq01685/SDLC/issues
Author-email: Lam Vuong <vuonglq01685@gmail.com>
License-Expression: MIT
Keywords: ai-agent,claude,codex,cursor,github,sdlc
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6.0
Description-Content-Type: text/markdown

# SDLC Framework

> Local-only, multi-AI SDLC framework. One `sdlc` CLI scaffolds a 4-phase project, auto-detects DoD evidence, dispatches the right specialist agent, and surfaces blockers via desktop notifications + GitHub issues.

[![PyPI](https://img.shields.io/pypi/v/sdlc-framework.svg)](https://pypi.org/project/sdlc-framework/)
[![Python](https://img.shields.io/pypi/pyversions/sdlc-framework.svg)](https://pypi.org/project/sdlc-framework/)

Works with **8 AI coding tools** out of the box: Claude Code · GitHub Copilot · Cursor · OpenAI Codex · Aider · Windsurf · Cline · Continue.

---

## What it does

```mermaid
flowchart LR
  Idea[Idea / brief] --> P1[📋 Phase 1<br/>Planning]
  P1 --> P2[🎨 Phase 2<br/>Design]
  P2 --> P3[💻 Phase 3<br/>Development]
  P3 --> P4[🚀 Phase 4<br/>Testing & Deploy]
  P4 -. metrics & feedback .-> P1
```

| Phase | Output | DoD highlight |
|---|---|---|
| 1. Planning | PRD, user stories, NFRs, stakeholder map, risks | PRD approved, NFRs quantified |
| 2. Design | C4 architecture, API spec, DB schema, UI/UX, ADRs, threat model | C4 reviewed, OpenAPI lint clean, STRIDE done |
| 3. Development | Coding/git/error/security standards, PR template, code-review checklist | Lint+test+security gating, AI disclosure in PR |
| 4. Testing & Deploy | Test plan, CI/CD, runbook, SLOs, incident response | 95% pass, SLO alerts wired, postmortem ready |

The engine **auto-scans your repo** every 3 seconds (when in watch mode), evaluates 28 DoD rules per `automation/rules.json`, and writes a JSON state file that the dashboard renders. AI agents read the same rules to know what evidence to produce next.

---

## Installation

```bash
uv tool install sdlc-framework        # recommended (uv manages a clean tool env)
# or
pip install --user sdlc-framework
```

Verify:

```bash
sdlc --version
# sdlc 0.6.0
```

---

## Quickstart — new project

```bash
mkdir my-app && cd my-app
sdlc setup     # interactive: scaffold + pick which AI tool(s) to install commands for
```

The wizard asks which AI coding tools you use (Claude Code / Cursor /
Copilot / Codex / Aider / Continue / Cline / Windsurf), auto-detects your
stack from `package.json` / `pyproject.toml` / `go.mod`, and writes
**tool-native artifacts** so you can stay inside your AI tool and use
slash commands instead of a terminal CLI.

Or skip the prompts:

```bash
sdlc setup --tools=claude-code,cursor --stack=node
```

### Then operate inside your AI tool

**Claude Code** — slash commands are wired:

```
/sdlc-start "Mobile task app for 5-person team"   begin Phase 1 (auto-invokes pm-agent subagent)
/sdlc-next                                        advance to the next pending item
/sdlc-scan                                        refresh progress summary
/sdlc-dispatch                                    inspect the full dispatch decision
/sdlc-dashboard                                   serve the live UI on localhost
```

The slash commands shell out to the `sdlc` CLI underneath; you don't need to
context-switch to a terminal.

**Cursor** — rules in `.cursor/rules/sdlc.mdc` are auto-loaded. Just share
your idea in chat; Cursor adopts the pm-agent persona. From Cursor's
integrated terminal you can also run `sdlc start "<idea>"` etc.

**GitHub Copilot Chat** — prompt files in `.github/prompts/sdlc-*.prompt.md`
are usable via the Copilot Chat prompts UI.

**Codex / Aider / Continue / Cline / Windsurf** — text rules at the project
root (`AGENTS.md`, `CONVENTIONS.md`, `.continuerules`, `.clinerules`,
`.windsurfrules`) are auto-loaded. From the tool's terminal you run the
`sdlc` CLI commands directly.

### Why an explicit subagent invocation?

In Claude Code, plugins like `superpowers:brainstorming` auto-fire on idea
prompts and write design specs into the wrong folder. The slash commands
this framework ships call **`use the pm-agent subagent`** explicitly,
which forces Claude Code to load `.claude/agents/pm-agent.md` (this repo's
authoritative role spec) and bypass conflicting plugins.

The first command scaffolds:

- 4 phase folders (`01-Planning/`, `02-Design/`, `03-Development/`, `04-Testing-Deploy/`) with **24 templates** + **4 standards docs** + **runbooks**.
- 9 specialist **agent definitions** (`agents/orchestrator.md`, `phase-1-pm.md`, ..., `cross/security-reviewer.md`).
- 8 **AI tool config files** at the project root (`CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`, etc.) — generated from a single shared source.
- `project.yaml` template — fill in name, team, tier (1=critical / 2=standard / 3=experiment), owners, GitHub URL.
- `automation/rules.json` — declarative DoD detection rules.
- `.github/workflows/ci.yml` (when stack is detected) — Node/Python/Go matrix CI template.

After init, edit `project.yaml`:

```yaml
schema_version: 1
name: my-app
team: platform
stack: node            # auto-detected; override with --stack at init
tier: 2                # 1=critical, 2=standard, 3=experiment
phase_target: 1        # the phase your team is currently focused on
repo_url: https://github.com/your-org/my-app
owners:
  sponsor: alice@org.com
  eng_lead: bob@org.com
  sre: dave@org.com
  # security: required when tier == 1
flags:
  ai_disclosure_required: true
  signoffs_strict: auto
```

---

## Quickstart — existing project

`sdlc init` is **idempotent** and **non-destructive**: it skips files that already exist. Drop it on top of any repo:

```bash
cd ~/Projects/existing-app           # has package.json / pyproject.toml / etc.
sdlc init                             # auto-detects stack, skips existing files
sdlc scan --print                     # see which DoD items are already satisfied
```

What you'll see on the first run:

- **Phase 1** is mostly red because PRD / user stories / NFRs likely don't exist yet → fill them in `01-Planning/templates/`.
- **Phase 3** "AI tool configs" + "coding standards" green because `sdlc init` just wrote them.
- **Phase 4** "CI/CD pipeline configured" green if the auto-detected `ci.yml` matches your stack; otherwise the existing workflow stays untouched.
- `owners-defined` red until you fill `project.yaml.owners`.

What `sdlc init` will **NOT** overwrite (unless `--force`):

- Your existing `README.md`, `LICENSE`, `package.json`, source code.
- `.github/workflows/ci.yml` if you already have one.
- `project.yaml` once you've edited it.

To force regeneration of a single file: delete it then re-run `sdlc init`. To force everything: `sdlc init --force` (use carefully).

---

## CLI reference

```text
# getting started (you usually only need `sdlc setup`)
sdlc setup [--tools=...] [--stack=...] [--force]  interactive: scaffold + pick AI tools
sdlc init [--stack=node|python|go] [--force]      scaffold without picking tools (low-level)
sdlc start "<your idea>"                          save the idea (used by /sdlc-start)
sdlc next [--json]                                show next pending DoD item (used by /sdlc-next)
sdlc resume                                       "where am I?" — phase, last activity, next action
                                                  (aliases: status, where)
sdlc replan [--scope=...] [--reason=...] [--clear] mark items dirty after a major change
                                                   --scope ∈ requirements / ui-ux / tech-stack /
                                                             scale-nfr / custom

# workflow
sdlc scan [--watch] [--interval N] [--print]      run the engine; write state.json
sdlc dispatch [--json] [--brief]                  next-agent decision + ready-to-paste brief
sdlc dashboard [--port N]                         serve dashboard/index.html on localhost

# integrations
sdlc agent-log start|done|fail <agent> <item>  append activity entry (50-line ring buffer)
sdlc notify <kind> <id> <title> <body>         desktop notification (osascript / notify-send)
sdlc gh-issue --clarification PATH | --gate ID file a GitHub Issue (idempotent)
sdlc gh-pr [--ready] [--base BRANCH]           open a Draft PR (or reuse existing)
sdlc build-ai-configs                          regenerate the 8 AI tool configs from shared sources

sdlc --version                                 print version
```

---

## Concepts

### `project.yaml` — tier-aware DoD strictness

The engine reads `project.yaml` and adjusts what evidence is required per tier:

| Rule | Tier 1 (critical) | Tier 2 (standard) | Tier 3 (experiment) |
|------|-------------------|-------------------|---------------------|
| `nfr-quantified` | needs `p99` AND (`RTO` or `RPO`) | `p95`/`p99` | optional |
| `threat-model` | STRIDE + `Mitigation` per asset | STRIDE only | optional |
| `tests-present` | required | recommended | optional |
| `prod-deploy-signoff` | sponsor + eng_lead + sre + security | sponsor + eng_lead + sre | eng_lead only |
| `owners-defined` | sponsor + eng_lead + security + sre | sponsor + eng_lead + sre | sponsor + eng_lead |

Missing `project.yaml` = engine uses `tier: 2` defaults; the `owners-defined` DoD item stays red until you fill the file in.

### Agent activity log

Every agent (Claude / Cursor / Codex / human dev) calls `sdlc agent-log start|done|fail` to append a JSONL entry to `automation/agent-runs.jsonl`. The dashboard renders the last 10 entries in a live "🤖 Agent activity" panel — so you can watch the loop without tailing a terminal.

```bash
SDLC_TOOL=claude-code sdlc agent-log start pm-agent prd-exists
# ... agent does work ...
sdlc agent-log done pm-agent prd-exists --summary="created 01-PRD.md"
```

### Desktop notifications

When the engine runs in `--watch` mode, every newly appearing clarification or pending gate fires a desktop notification:

- macOS — `osascript display notification` (sound on gate)
- Linux — `notify-send -u critical|normal --app-name=SDLC`
- elsewhere — silent fallback (log line still written to `automation/notifications.log`)

Notifications are **transition-only**: an item that stays pending across many scans only fires once. Engine startup baselines and does not spam.

### TDD enforcement (mandatory)

A built-in DoD rule `tdd-coverage` (phase 3) enforces **strict 1:1 TDD pairing across every tier** — no opt-out. Every source file in `src/**` must have at least one matching test file. The only allowance is when no source files exist yet (vacuous pass for fresh projects).

The rule scans `src/**/*.{ts,tsx,js,jsx,py,go}` for source and `{src,tests}/**/*{.test,.spec,_test}.{ts,...}` for tests. Test files are excluded from the source count (so `foo.test.ts` doesn't count as both).

If your team explicitly does not want TDD (e.g. spike branches), delete this rule from `automation/rules.json` — but the framework's default is **TDD-required**.

For per-feature TDD enforcement, set `tdd: true` on a `custom_items` entry — the engine auto-derives a `tdd_pairing` check from your code glob:

```yaml
custom_items:
  - id: feature-auth
    label: "Auth feature (TDD enforced)"
    phase: 3
    tdd: true                                  # ⭐ enforces test pairing
    checks:
      - type: file_glob_min_count
        glob: "src/auth/**/*.ts"                # the engine derives test_glob:
        min: 1                                  # src/auth/**/*.test.ts
```

The auto-derived test glob inserts `.test.` before the extension. Override explicitly with `code_glob` and `test_glob` if you use a different convention:

```yaml
custom_items:
  - id: feature-billing
    label: "Billing (TDD)"
    phase: 3
    tdd: true
    code_glob: "src/billing/**/*.py"
    test_glob: "tests/billing/**/test_*.py"
    min_ratio: 1.0
    checks: []
```

Failure messages are explicit:
```
✗ tdd: 0 test(s) < 1 required (1 src × 1.00) — write tests first
```

You can also use the `tdd_pairing` check type directly in your own custom items if you need precise control:

```yaml
custom_items:
  - id: my-tdd-rule
    label: "My TDD rule"
    phase: 3
    checks:
      - type: tdd_pairing
        code_glob: "lib/**/*.go"
        test_glob: "lib/**/*_test.go"
        min_ratio: 1.0
        allow_empty: true   # vacuous pass when no source files yet (default true)
```

### Custom items — track per-feature progress in phase 3

Phase 3 by default measures "development infrastructure ready" (standards published, AI configs wired, PR template, security checklist) — NOT "how many features you've shipped". To track per-feature/milestone progress, declare `custom_items` in `project.yaml`:

```yaml
custom_items:
  - id: feature-auth
    label: "Auth feature: login + signup"
    phase: 3
    checks:
      - type: file_glob_min_count
        glob: "src/auth/**/*.ts"
        min: 1
      - type: file_glob_min_count
        glob: "src/auth/**/*.test.ts"
        min: 1
  - id: feature-billing
    label: "Billing: Stripe integration"
    phase: 3
    checks:
      - type: file_glob_min_count
        glob: "src/billing/**/*.ts"
        min: 1
```

The engine evaluates them like framework rules. They appear in the phase tracker and contribute to `done_pct`. Use any check type the engine supports (`file_glob_min_count`, `file_contains_all`, `file_contains_any`, `regex_min_count`, `file_exists`, etc.).

This lets you answer "code đến phần nào" — auth feature ✓, billing ✗ (still building), dashboard ✗.

### Why phase 1 / 2 may be empty after `sdlc init`

DoD rules use **non-recursive globs** (`01-Planning/*PRD*.md`, not `**/*PRD*.md`) so that template files in `templates/` directories don't count as deliverables. After `sdlc init` you'll see Phase 1 at 0/7 — that's correct: you haven't written the actual PRD / user stories / requirements yet. The framework ships templates as starting points; filling them in is your work.

Phase 3 starts at ~5/7 ✓ because the framework ships the standards + PR template + AI tool configs (real files). That's the development infrastructure being ready, not features being done. Use `custom_items` (above) to add feature-level tracking.

### Resume support

Stepped away for a day or a week? `sdlc resume` answers "where am I and what do I do next" in a single screen:

```bash
$ sdlc resume
📍 my-app — 79% done (22/28 items)
⏳ Currently pending: phase 1 · owners-defined — Project owners defined per tier
🕐 Last activity: pm-agent finished prd-exists · 2h ago
✋ 1 open clarification(s):
     · automation/clarifications/002-target-rps.md
🔒 1 pending gate(s):
     · phase4-prod (phase 4) — needs sponsor, eng_lead, sre

Next steps:
  → Resolve clarification first: edit automation/clarifications/002-target-rps.md
    Change `STATUS: open` → `STATUS: resolved`, then `sdlc scan`.
```

The dashboard's **Resume** card surfaces the same info with a one-click "Copy /sdlc-next" button. Aliases: `sdlc status`, `sdlc where`. Use `--json` for scripting.

### Replan workflow — handle mid-project changes

What if you're at Phase 3 and the requirements change? Or you decide to switch tech stacks? Edit the source files, then run `sdlc replan` to mark downstream DoD items dirty so the engine forces them red until you redo the work:

```bash
$ sdlc replan
What changed? Pick one:
  1. Functional requirements / user stories changed
  2. UI / UX scope or screens changed
  3. Tech stack / language / framework changed
  4. Scale / NFR targets (RPS, latency, SLO) changed
  5. Custom — I'll list the item ids myself
  6. Clear all dirty markers (I've redone the work)
> 3
This will mark 12 item(s) dirty:
     · architecture-doc
     · api-spec
     · db-schema
     ... (12 total)
Why (one line for the audit log)?
> switching from Node to Python
Apply? [Y/n] y

[sdlc replan] marked 12 item(s) dirty.
[sdlc replan] wrote audit clarification: automation/clarifications/replan-20260501T101200Z.md
```

The dashboard surfaces a top banner "🔁 Replan in progress — N items dirty" so the team sees it. The engine respects `automation/.replan.json` (gitignored) — affected items show ✗ even when their evidence files still exist. After redoing the work, run `sdlc replan --clear` to drop the markers.

Flag-mode (no prompts) for automation:

```bash
sdlc replan --scope=tech-stack --reason="Node → Python"
sdlc replan --scope=custom --items=api-spec,tests-present --reason="API redesign"
sdlc replan --clear
```

Each replan also writes an audit clarification under `automation/clarifications/replan-<ts>.md` so the change is visible alongside other STOP triggers.

### Smart dispatcher

`sdlc dispatch` (or the engine's `state.next_dispatch` field) returns:

- The **primary agent** for the next pending DoD item.
- A `parallel_agents` list — cross-cutting agents the orchestrator should invoke in parallel (e.g. `api-spec` done → invite `security-reviewer`).
- A `blocked_by` field — names the earlier-phase blocker (gate / clarification / high-risk path) when phase preference can't be honored.

It also reads `project.yaml.phase_target`: if the team has declared they're focused on phase 3, the dispatcher prefers phase 3 items unless an earlier phase has a hard blocker.

### GitHub integration

Two wrappers surface STOP triggers from the local repo to GitHub via the `gh` CLI:

```bash
sdlc gh-issue --clarification automation/clarifications/001-foo.md
# → creates a GitHub Issue with body=clarification content + sdlc-clarification label
# → writes `issue_url:` back into the file (idempotent on re-run)

sdlc gh-issue --gate phase4-prod
# → creates "🔒 Gate pending: <label>" issue, writes URL into automation/signoffs/<id>.yaml

sdlc gh-pr [--ready] [--base main]
# → opens a Draft PR (or reuses existing) with auto-summary
```

Both exit 0 when `gh` is missing/unauthenticated — agents call them unconditionally; nothing breaks offline. The engine reads `issue_url` back into `state.json` and the dashboard shows a small ↗ icon next to each item.

### Autonomous loop (`automation/AGENT-LOOP.md`)

When operating without a human in the loop, AI agents follow `AGENT-LOOP.md`:

1. Read `state.json` → know what's pending.
2. Read `rules.json` → know what evidence to produce.
3. Plan → execute → verify (re-scan engine) → commit.
4. **STOP triggers** (write a clarification file then halt):
   - 🔍 Ambiguity (insufficient information)
   - ⚔️ Conflict (two sources disagree)
   - 🚪 Gate (sign-off needed)
   - 🛑 High-risk path (auth / crypto / payment / migrations / secrets)

Resolve a clarification: edit the file, change `STATUS: open` → `STATUS: resolved`. Approve a gate: write `automation/signoffs/<gate-id>.yaml` with `approved: true`.

---

## AI tool support

The package ships **one shared source** in `ai-tools/shared-prompts/standards.md` plus a small per-tool header. `sdlc init` (and `sdlc build-ai-configs`) generates 8 tool-specific configs:

| Tool | Output path | Auto-loaded |
|---|---|---|
| Claude Code / Desktop / Agent SDK | `CLAUDE.md` | ✅ |
| GitHub Copilot | `.github/copilot-instructions.md` | ✅ |
| Cursor | `.cursorrules` | ✅ |
| OpenAI Codex / agent | `AGENTS.md` | ✅ |
| Aider | `.aider.conf.yml` + `CONVENTIONS.md` | ✅ |
| Windsurf | `.windsurfrules` | ✅ |
| Cline | `.clinerules` | ✅ |
| Continue | `.continue/config.json` + `.continuerules` | ✅ |

Edit the shared source, run `sdlc build-ai-configs`, and all 8 files regenerate. Each generated file carries a `<!-- AUTO-GENERATED -->` header so devs don't hand-edit them.

---

## Specialist agents

The `agents/` directory ships **9 role specs** that any AI coding tool can read:

| Agent | Role |
|---|---|
| `orchestrator` | Reads state, picks next agent (mirrors `sdlc dispatch`). |
| `pm-agent` (Phase 1) | PRDs, user stories with G/W/T, quantified NFRs. |
| `architect-agent` (Phase 2) | C4, API spec, DB schema, ADRs, STRIDE. |
| `developer-agent` (Phase 3) | Coding standards, PR/CR checklists. |
| `sre-agent` (Phase 4) | CI/CD, deploy runbooks, SLOs, incident response. |
| `security-reviewer` (cross) | AppSec review on auth/data/crypto-touching changes. |
| `test-author` (cross) | Test strategy + actual test files. |
| `doc-keeper` (cross) | Sync docs with behavior changes. |
| `clarification-triager` (cross) | Triages ambiguity into structured clarification files. |

Same roster ships in `.claude/agents/` (Claude Code subagent format with frontmatter). Other tools read `agents/*.md` directly per their conventions.

---

## Dashboard

A compact ops-console — single viewport, no swipe — auto-fetches `dashboard/state.json` every 3 seconds. Layout from top to bottom:

- **Top header**: live status dot (green = OK, amber = "needs you", red = offline), project name (clickable link to `repo_url`), team, tier, focus phase, overall %, branch, last scan time.
- **Alert banners**: prominent amber/red banners surface every open clarification, every pending gate, and any active replan. Each banner has a one-click `[Copy path]` button so you can paste the file path into your editor immediately. GitHub issue ↗ links appear when `sdlc gh-issue` has filed one.
- **"You are here" card**: phase + active item + failure reason inline + paste-ready `/sdlc-next` prompt with a `[Copy]` button.
- **Phase tracker**: vertical list of all 4 phases (no swiping needed). Each phase row shows progress bar + every item with ✓ / 🔒 / · markers and the failing-rule message inline. The currently-active item is outlined.
- **Side column** (desktop ≥ 1100px):
  - **Resume** card — last agent activity + relative timestamp ("2h ago") + Copy `/sdlc-next` button.
  - **Project** info — stack, tier, phase target, owners.
  - **Activity timeline** — last 12 agent runs with `agent · item · duration` and timestamps.
  - **Quick links** — README, AGENT-LOOP, rules.json.

Run `sdlc scan --watch` in one terminal and `sdlc dashboard` in another:

```bash
sdlc scan --watch                # re-scans every 3 s, fires desktop notifications on transitions
sdlc dashboard --port 8765       # serves http://localhost:8765/dashboard/
```

Buttons that actually work: every `[Copy]` button uses `navigator.clipboard.writeText` and fires a `copied` toast. Every alert links to the underlying file path. The status dot changes to amber automatically when a clarification or gate appears, so an open browser tab signals "needs you" without needing notifications enabled.

---

## Architecture

```
your-repo/
├── project.yaml                                # metadata (engine reads this)
├── 01-Planning/                                # Phase 1 templates + your filled-in artifacts
├── 02-Design/                                  # Phase 2 ditto
├── 03-Development/                             # Phase 3 ditto
│   └── standards/                              # coding-standards, git-workflow, error-handling, security-checklist
├── 04-Testing-Deploy/                          # Phase 4 ditto
│   └── templates/ci-workflows/                 # node-ci.yml / python-ci.yml / go-ci.yml
├── agents/                                     # role specs read by AI tools
├── ai-tools/
│   ├── shared-prompts/standards.md             # source of truth for all tool configs
│   └── <tool>/                                 # AUTO-GENERATED per-tool config files
├── automation/
│   ├── rules.json                              # declarative DoD detection
│   ├── state.json                              # AUTO-GENERATED snapshot (gitignored)
│   ├── clarifications/*.md                     # AI raises STOPs here, user resolves
│   ├── signoffs/<gate-id>.yaml                 # user approves gates here
│   ├── agent-runs.jsonl                        # AUTO-GENERATED activity log (gitignored)
│   └── notifications.log                       # AUTO-GENERATED notify history (gitignored)
├── dashboard/
│   ├── index.html                              # bundled UI
│   └── state.json                              # mirror of automation/state.json
├── .github/workflows/ci.yml                    # selected CI template
├── CLAUDE.md / .cursorrules / AGENTS.md / ...  # 8 AI tool configs (auto-generated)
└── .gitignore
```

State flows: AI agent does work → engine scans → writes `state.json` → dashboard fetches → dispatcher decides → next agent.

---

## Development (contributing to this framework)

```bash
git clone https://github.com/vuonglq01685/SDLC.git
cd SDLC
python3 -m pip install --user -e .
python3 -m pip install --user -r automation/requirements-dev.txt

python3 -m pytest automation/tests/ -v       # 47 tests
bash scripts/tests/test_setup.sh             # smoke
bash scripts/tests/test_agent_log.sh
bash scripts/tests/test_notify.sh
bash scripts/tests/test_gh_wrappers.sh

# After editing scaffold templates, sync into the package:
bash scripts/sync-scaffold.sh

# Build wheel + sdist:
python3 -m build
```

The framework eats its own dog food: it has its own `project.yaml`, runs its own engine on itself, and the `owners-defined` rule is intentionally red here so you can see it work in the dashboard.

---

## License

MIT.

## Links

- [PyPI](https://pypi.org/project/sdlc-framework/)
- [GitHub](https://github.com/vuonglq01685/SDLC)
- C4 model — https://c4model.com
- OWASP ASVS — https://owasp.org/www-project-application-security-verification-standard/
- Conventional Commits — https://www.conventionalcommits.org
