optimize redme
This commit is contained in:
@@ -1,429 +1,310 @@
|
|||||||
# CASAN AI-SDLC
|
# CASAN
|
||||||
|
|
||||||
CASAN là governance harness cho AI Software Development Life Cycle. Harness có
|
CASAN là governance harness cho agentic coding. CASAN được cài một lần trên máy
|
||||||
thể được cài một lần ở máy developer rồi adopt vào nhiều dự án hiện hữu mà không
|
developer, sau đó được liên kết vào từng repository bằng project hooks. CASAN
|
||||||
copy toàn bộ CASAN hoặc dựng lại project shell.
|
không thay thế IDE, coding agent hoặc workflow phát triển của project.
|
||||||
|
|
||||||
> **Bắt đầu nhanh:** xem [CASAN Quick Start](#casan-quick-start). Tài liệu chi
|
Project có thể tiếp tục dùng nguyên trạng slash commands, agents, skills, review
|
||||||
> tiết: [cài đặt hybrid](docs/casan/CASAN_INSTALL_HYBRID.md),
|
loops và cấu trúc source hiện hữu. CASAN không áp đặt một pipeline hoặc số bước
|
||||||
> [dùng CASAN cho dự án thực tế](docs/guides/CASAN_USING_FOR_REAL_PROJECTS_VI.md)
|
cố định.
|
||||||
> và [tạo project shell production](docs/guides/CASAN_PROJECT_SHELL_PRODUCTION.md).
|
|
||||||
|
|
||||||
## Table of Contents
|
## Trạng thái sản phẩm
|
||||||
|
|
||||||
- [CASAN Quick Start](#casan-quick-start)
|
| Thành phần | Trạng thái | Phạm vi |
|
||||||
- [Project Objectives](#project-objectives)
|
|---|---|---|
|
||||||
- [Dùng CASAN cho dự án thực tế](docs/guides/CASAN_USING_FOR_REAL_PROJECTS_VI.md)
|
| Core — Level 1 | Implemented | H1–H7 harness, hooks, policy gates, audit, evidence và CLI |
|
||||||
- [CASAN Project Shell production](docs/guides/CASAN_PROJECT_SHELL_PRODUCTION.md)
|
| DevKit — Level 2 | Implemented | Core + `casan init`, domain-pack và CI template |
|
||||||
- [Requirements](#requirements)
|
| Platform — Level 3 | Preview | Control Panel được deploy riêng, không được cài vào project bằng `casan init` |
|
||||||
- [Input for Flow](#input-for-flow)
|
| Enterprise — Level 4 | Chưa phát hành | Installer chủ động từ chối |
|
||||||
- [Output for Flow](#output-for-flow)
|
|
||||||
- [Optional Reference AI-SDLC Flow](#optional-reference-ai-sdlc-flow)
|
|
||||||
- [Reference Steps](#reference-steps)
|
|
||||||
- [Flow Diagram](#flow-diagram)
|
|
||||||
- [Legend](#legend)
|
|
||||||
- [Agents](#agents)
|
|
||||||
- [Spec-Kit Agents (Core Flow)](#spec-kit-agents-core-flow)
|
|
||||||
- [FPT-Defined Agents (IPA Gen + Review + Orchestrator + Test)](#fpt-defined-agents-ipa-gen--review--orchestrator--test)
|
|
||||||
- [AI-SDLC Usage Guide](#ai-sdlc-usage-guide)
|
|
||||||
- [Directory Structure](#directory-structure)
|
|
||||||
- [Directory Details](#directory-details)
|
|
||||||
|
|
||||||
## CASAN Quick Start
|
Đối với repository đã có sẵn vỏ dự án, nên dùng **Level 1 cho project**. Chỉ
|
||||||
|
chọn Level 2 khi project thực sự cần domain-pack và CI template của CASAN.
|
||||||
|
|
||||||
### 1. Cài CASAN một lần trên máy developer
|
## Quick start
|
||||||
|
|
||||||
Yêu cầu chung: Python 3. Trên macOS/Linux cần Bash; trên Windows cần PowerShell
|
### Yêu cầu
|
||||||
và Git for Windows (Git Bash).
|
|
||||||
|
|
||||||
macOS/Linux, chạy từ checkout CASAN:
|
- macOS/Linux: Python 3 và Bash.
|
||||||
|
- Windows: PowerShell 5.1+, Python 3 và Git for Windows/Git Bash.
|
||||||
|
- Client tương ứng nếu cần: Claude Code, Codex hoặc VS Code.
|
||||||
|
|
||||||
|
### 1. Cài CASAN một lần trên máy
|
||||||
|
|
||||||
|
Từ checkout hoặc release bundle của CASAN:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# macOS/Linux
|
||||||
sh install.sh --level devkit
|
sh install.sh --level devkit
|
||||||
# Nếu installer báo launcher chưa nằm trên PATH:
|
|
||||||
|
# Nếu launcher chưa nằm trên PATH
|
||||||
export PATH="${CASAN_HOME:-$HOME/.casan}/bin:$PATH"
|
export PATH="${CASAN_HOME:-$HOME/.casan}/bin:$PATH"
|
||||||
|
|
||||||
casan version
|
casan version
|
||||||
```
|
```
|
||||||
|
|
||||||
Windows PowerShell, chạy từ checkout CASAN:
|
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
# Windows PowerShell
|
||||||
pwsh .\install.ps1
|
pwsh .\install.ps1
|
||||||
```
|
|
||||||
|
|
||||||
Sau lần cài đầu tiên trên Windows, mở PowerShell mới rồi kiểm tra:
|
# Mở terminal mới sau khi installer cập nhật user PATH
|
||||||
|
|
||||||
```powershell
|
|
||||||
casan version
|
casan version
|
||||||
```
|
```
|
||||||
|
|
||||||
Mặc định harness được cài tại `~/.casan` trên macOS/Linux và
|
Gói global `devkit` được dùng vì nó chứa lệnh adoption `casan init`. Harness
|
||||||
`%LOCALAPPDATA%\casan` trên Windows.
|
được cài mặc định tại:
|
||||||
|
|
||||||
### 2. Adopt CASAN vào dự án
|
- macOS/Linux: `~/.casan`
|
||||||
|
- Windows: `%LOCALAPPDATA%\casan`
|
||||||
|
|
||||||
Chạy tại root của dự án cần bảo vệ:
|
### 2. Adopt vào repository hiện hữu
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd <project-root>
|
cd <project-root>
|
||||||
casan init
|
|
||||||
```
|
|
||||||
|
|
||||||
Trong terminal tương tác, `casan init` hiển thị menu cho phép chọn một hoặc
|
# Chỉ thêm governance config/hooks; không thêm domain-pack hoặc CI template
|
||||||
nhiều integration:
|
casan init --level core --client claude,codex --mode enforce
|
||||||
|
|
||||||
1. Claude Code
|
|
||||||
2. Codex
|
|
||||||
3. GitHub Copilot trong VS Code
|
|
||||||
|
|
||||||
Có thể cấu hình không tương tác:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
casan init --client claude
|
|
||||||
casan init --client claude,codex
|
|
||||||
casan init --client vscode-copilot --vscode-install yes
|
|
||||||
casan init --client all
|
|
||||||
```
|
|
||||||
|
|
||||||
Mặc định production là `--mode enforce`. Chỉ dùng `--mode observe` cho giai
|
|
||||||
đoạn pilot telemetry-only.
|
|
||||||
|
|
||||||
`casan init` an toàn với dự án đã có project shell, agents, skills hoặc hooks:
|
|
||||||
|
|
||||||
- Không sửa source code và không dựng lại vỏ dự án.
|
|
||||||
- Merge idempotent vào `.claude/settings.json`, `.codex/hooks.json` và
|
|
||||||
`.vscode/extensions.json`.
|
|
||||||
- Giữ nguyên cấu hình/hook của dự án; chạy lại không tạo hook CASAN trùng lặp.
|
|
||||||
- Chỉ ghi bootstrap/config per-project; harness vẫn dùng bản global đã pin hash.
|
|
||||||
|
|
||||||
Nếu ứng dụng tự gọi LLM API qua backend riêng, ngoài Claude Code/Codex/Copilot,
|
|
||||||
luồng đó không tự động đi qua project hooks và cần adapter CASAN riêng.
|
|
||||||
|
|
||||||
Với project đã adopt CASAN theo mô hình cũ và đang chứa
|
|
||||||
`packages/casan-harness`, init nhận diện đây là vendored application thay vì
|
|
||||||
source hub:
|
|
||||||
|
|
||||||
- Không cần `--force`.
|
|
||||||
- Không xóa harness, scripts, workflow hoặc evidence cũ.
|
|
||||||
- Tự nâng cấp các block nằm giữa marker `CASAN_PROMPT_ENFORCEMENT_START/END`.
|
|
||||||
- Báo rõ file nào còn prose legacy ngoài marker cần review thủ công.
|
|
||||||
|
|
||||||
### 3. Hành vi chat theo client
|
|
||||||
|
|
||||||
| Client đã enable | Prompt đi qua CASAN | Onboarding bắt buộc |
|
|
||||||
|---|---|---|
|
|
||||||
| Claude Code CLI/extension | Tự động với chat bình thường | Mở project ở trusted workspace |
|
|
||||||
| Codex CLI/extension | Tự động với chat bình thường | Mở `/hooks`, review và trust đúng hook hash |
|
|
||||||
| GitHub Copilot Chat | Chỉ khi gửi `@casan <prompt>` | Cài CASAN VSIX; built-in Copilot chat không bị global-intercept |
|
|
||||||
|
|
||||||
Không cần chỉ định một “CASAN agent” khi chat bằng Claude Code hoặc Codex.
|
|
||||||
GitHub Copilot là ngoại lệ: VS Code không cung cấp API cho extension intercept
|
|
||||||
mọi built-in Copilot prompt, nên CASAN cung cấp route explicit `@casan`.
|
|
||||||
|
|
||||||
### 4. Kiểm tra sau khi init
|
|
||||||
|
|
||||||
```bash
|
|
||||||
casan doctor
|
casan doctor
|
||||||
casan verify-harness
|
casan verify-harness
|
||||||
```
|
```
|
||||||
|
|
||||||
Với Codex, `doctor` kiểm tra config/bootstrap/runtime nhưng bước trust vẫn phải
|
`casan init` có menu chọn client khi chạy tương tác. Trong automation nên chỉ
|
||||||
thực hiện trong `/hooks`. Với Copilot, nếu máy chưa có `code` CLI, init trả về
|
định rõ `--client`:
|
||||||
đường dẫn VSIX để cài bằng lệnh **Extensions: Install from VSIX...**.
|
|
||||||
|
|
||||||
Khi nâng cấp global CASAN, chạy lại `casan init` trong project để cập nhật
|
```bash
|
||||||
bootstrap và pin hash mới. Xem đầy đủ tùy chọn và troubleshooting tại
|
casan init --level core --client claude
|
||||||
[CASAN_INSTALL_HYBRID.md](docs/casan/CASAN_INSTALL_HYBRID.md).
|
casan init --level core --client codex
|
||||||
|
casan init --level core --client claude,codex
|
||||||
### 5. CASAN không yêu cầu flow 13 bước
|
casan init --level core --client vscode-copilot --vscode-install yes
|
||||||
|
casan init --level core --client all
|
||||||
CASAN governance chạy theo từng prompt/tool turn của IDE đã enable, độc lập với
|
|
||||||
workflow nghiệp vụ của project. Vì vậy project hiện hữu có thể giữ nguyên:
|
|
||||||
|
|
||||||
- Slash commands riêng như `/bd:boss`, `/bd:generation`, `/bd:review`.
|
|
||||||
- Agents, skills, prompts và hooks đã có trong `.claude/`, `.codex/`,
|
|
||||||
`.github/` hoặc thư mục riêng.
|
|
||||||
- Số bước, thứ tự bước, vòng review và cấu trúc source hiện tại.
|
|
||||||
|
|
||||||
Không cần đổi workflow đó sang `casan.pipeline`. Pipeline 13 bước bên dưới chỉ
|
|
||||||
là flow tham chiếu tùy chọn đi kèm repository này. Sau `casan init`, chat và
|
|
||||||
tool calls qua Claude Code/Codex vẫn được CASAN kiểm soát dù người dùng gọi
|
|
||||||
agent/command riêng hoặc không chỉ định agent CASAN. Với GitHub Copilot Chat,
|
|
||||||
vẫn phải dùng route explicit `@casan`.
|
|
||||||
|
|
||||||
Chỉ cần tích hợp thêm adapter nếu ứng dụng tự gọi LLM API ngoài các IDE hooks.
|
|
||||||
Nếu muốn CI hoặc một workflow tùy biến có chứng nhận end-to-end riêng, có thể
|
|
||||||
gọi CASAN CLI tại các gate phù hợp; đây là tăng cường tùy chọn, không phải điều
|
|
||||||
kiện để CASAN hoạt động.
|
|
||||||
|
|
||||||
## Project Objectives
|
|
||||||
|
|
||||||
Apply AI to the SDLC process to automate and optimize the creation of software products from initial requirements to complete source code.
|
|
||||||
|
|
||||||
## Requirements
|
|
||||||
- **Flow + Prompt + Template**: **Spec-Kit**
|
|
||||||
- **AI Tool của flow demo/legacy**: **Claude Code** là assistant chính; CASAN
|
|
||||||
harness và Control Panel có thể chạy độc lập bằng browser/CLI/CI hoặc dùng model
|
|
||||||
local/OmniRoute.
|
|
||||||
- **AI-SDLC**: AI-integrated SDLC process **Spec-Kit Modified** (Add IPA Gen + Review Loop + Orchestrator)
|
|
||||||
- **IPA Template**: Following IPA (Information-technology Promotion Agency) template standards
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Input for Flow
|
|
||||||
|
|
||||||
- `apps/<project-id>/domain/input/requirement.md` — project requirements
|
|
||||||
- `apps/<project-id>/domain/input/architecture.md` — architecture and constraints
|
|
||||||
- Project-owned input, reference, agent, and skill directories remain untouched
|
|
||||||
|
|
||||||
## Output for Flow
|
|
||||||
|
|
||||||
| Output | Location | Description |
|
|
||||||
|--------|----------|-------------|
|
|
||||||
| **IPA Docs** (SRS, BD, DD, Test Cases, Test Reports) | `docs/output/ipa-docs/` | Design documents generated by IPA agents (organized in `srs/`, `bd/`, `dd/`, `testcase/`, `testreport/` subdirectories) |
|
|
||||||
| **AI Agent Logs** | `docs/output/output_logs/` | Execution logs from AI agents |
|
|
||||||
| **SRS-Systems** | `docs/output/srs-systems/` | System-wide SRS (generated once during input clarification phase, not part of the main flow steps) |
|
|
||||||
| **Spec-Kit Artifacts** | `specs/[FEATURE_NAME]/` | Feature artifacts generated by Spec-Kit agents (`spec.md`, `plan.md`, `tasks.md`, contracts, checklists) |
|
|
||||||
| **Source Code** | Project-defined locations | CASAN does not impose an application framework or source layout |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Optional Reference AI-SDLC Flow
|
|
||||||
|
|
||||||
CASAN governance không phụ thuộc vào flow này. Repository cung cấp
|
|
||||||
**`casan.pipeline`** như một orchestrator tham chiếu tùy chọn cho những project
|
|
||||||
muốn dùng Spec-Kit + IPA theo trình tự bên dưới. Project có workflow riêng
|
|
||||||
không cần cài, gọi hoặc chuyển đổi sang pipeline này.
|
|
||||||
|
|
||||||
### Reference Steps
|
|
||||||
|
|
||||||
| Step | Agent | Output | Category |
|
|
||||||
|------|-------|--------|----------|
|
|
||||||
| **STEP 1** | `casan.srs` | SRS (ソフトウェア要件定義書) | 📄 IPA Doc Gen |
|
|
||||||
| **STEP 2** | `casan.bd` | BD — 外部設計 (Basic Design) | 📄 IPA Doc Gen |
|
|
||||||
| **STEP 3** | `speckit.specify` | `spec.md` | 📝 Spec-Kit |
|
|
||||||
| **STEP 4** | `speckit.clarify` | Resolve ambiguities (NO PAUSE) | 📝 Spec-Kit |
|
|
||||||
| **STEP 5** | `casan.reviewspec` 🔄 | Spec review (auto-retry) | 🔍 Agent Review |
|
|
||||||
| **STEP 6** | `speckit.plan` | `plan.md` + data-model + contracts | 📝 Spec-Kit |
|
|
||||||
| **STEP 7** | `casan.reviewplan` 🔄 | Plan review (auto-retry) | 🔍 Agent Review |
|
|
||||||
| **STEP 8** | `casan.dd` | DD — 内部設計 (Detail Design) | 📄 IPA Doc Gen |
|
|
||||||
| **STEP 8b** | `casan.testkit` | Test cases (`gen-testcases`) | 🧪 Test |
|
|
||||||
| **STEP 9** | `speckit.tasks` | `tasks.md` | 📝 Spec-Kit |
|
|
||||||
| **STEP 10** | `speckit.implement` 🔄 | Implementation + build & fix (auto-retry) | 📝 Spec-Kit |
|
|
||||||
| **STEP 11** | `casan.reviewcode` 🔄 | Code review + DB data check (auto-retry) | 🔍 Agent Review |
|
|
||||||
| **STEP 12** | `casan.testkit` 🔄 | Run tests (`run-tests`) — BACK-TO-PLAN on fail | 🧪 Test |
|
|
||||||
| **STEP 13** | Boss (direct) | Build BE + connect DB + Build FE + Launch UI → `open_browser_page` | 🚀 Deploy |
|
|
||||||
|
|
||||||
### Flow Diagram
|
|
||||||
|
|
||||||
```
|
|
||||||
┌─────────────────────────────────────────────────────────────┐
|
|
||||||
│ INPUT │
|
|
||||||
│ [ Raw Requirement ] [ Clear Requirement ] [ Tech Stack ] │
|
|
||||||
└──────────────────────────────┬──────────────────────────────┘
|
|
||||||
│
|
|
||||||
┌────────────────────┴──── (one-time, pre-flow) ────┐
|
|
||||||
│ casan.srs → docs/output/srs-systems/ │
|
|
||||||
└────────────────────┬──────────────────────────────┘
|
|
||||||
│
|
|
||||||
╔════════════════════════════╧══════════════════════════════════╗
|
|
||||||
║ casan.pipeline (Orchestrator) ║
|
|
||||||
║ ║
|
|
||||||
║ ┌─── IPA Doc Gen ───────────────────────────────────────┐ ║
|
|
||||||
║ │ STEP 1 casan.srs → SRS │ ║
|
|
||||||
║ │ STEP 2 casan.bd → BD (外部設計) │ ║
|
|
||||||
║ └───────────────────────────────────────────────────────┘ ║
|
|
||||||
║ │ ║
|
|
||||||
║ ▼ ║
|
|
||||||
║ ┌─── Spec-Kit + Review Loop ────────────────────────────┐ ║
|
|
||||||
║ │ STEP 3 speckit.specify → spec.md │ ║
|
|
||||||
║ │ STEP 4 speckit.clarify → resolve ambiguities │ ║
|
|
||||||
║ │ STEP 5 casan.reviewspec 🔄 auto-retry │ ║
|
|
||||||
║ │ │ │ ║
|
|
||||||
║ │ ▼ │ ║
|
|
||||||
║ │ STEP 6 speckit.plan → plan.md + data-model │ ║
|
|
||||||
║ │ STEP 7 casan.reviewplan 🔄 auto-retry │ ║
|
|
||||||
║ └───────────────────────────────────────────────────────┘ ║
|
|
||||||
║ │ ║
|
|
||||||
║ ▼ ║
|
|
||||||
║ ┌─── IPA Doc Gen (Detail) ──────────────────────────────┐ ║
|
|
||||||
║ │ STEP 8 casan.dd → DD (内部設計) │ ║
|
|
||||||
║ │ STEP 8b casan.testkit → gen-testcases │ ║
|
|
||||||
║ └───────────────────────────────────────────────────────┘ ║
|
|
||||||
║ │ ║
|
|
||||||
║ ▼ ║
|
|
||||||
║ ┌─── Implementation ───────────────────────────────────┐ ║
|
|
||||||
║ │ STEP 9 speckit.tasks → tasks.md │ ║
|
|
||||||
║ │ STEP 10 speckit.implement 🔄 build & fix │ ║
|
|
||||||
║ │ STEP 11 casan.reviewcode 🔄 code review │ ║
|
|
||||||
║ │ STEP 12 casan.testkit 🔄 run-tests │ ║
|
|
||||||
║ │ (BACK-TO-PLAN on fail) │ ║
|
|
||||||
║ └──────────────────────────────────────────────────────┘ ║
|
|
||||||
║ │ ║
|
|
||||||
║ ▼ ║
|
|
||||||
║ ┌─── Deploy ───────────────────────────────────────────┐ ║
|
|
||||||
║ │ STEP 13 Boss → build BE + DB + FE → open_browser │ ║
|
|
||||||
║ └──────────────────────────────────────────────────────┘ ║
|
|
||||||
║ ║
|
|
||||||
╚══════════════════════════════════════════════════════════════╝
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Legend
|
Với Codex, sau init phải mở `/hooks`, kiểm tra và trust đúng project hook hash.
|
||||||
|
|
||||||
| Symbol | Meaning |
|
### 3. Dùng project bình thường
|
||||||
|--------|---------|
|
|
||||||
| 🔄 | Auto-retry loop (agent retries until pass) |
|
|
||||||
|
|
||||||
---
|
Không cần gọi CASAN agent hoặc CASAN pipeline. Tiếp tục dùng workflow hiện hữu,
|
||||||
|
ví dụ `/bd:boss`, `/bd:generation`, `/bd:review`, hoặc chat bình thường không
|
||||||
|
chỉ định agent.
|
||||||
|
|
||||||
## Agents
|
CASAN tự tham gia vào lifecycle của client đã enable:
|
||||||
|
|
||||||
### Spec-Kit Agents (Core Flow)
|
1. `UserPromptSubmit`: admission và quét prompt.
|
||||||
|
2. `PreToolUse`: kiểm tra tool input và chặn side effect không hợp lệ.
|
||||||
|
3. `PostToolUse`: ghi evidence của tool result.
|
||||||
|
4. `Stop`: finalize trace, telemetry và trạng thái certification.
|
||||||
|
|
||||||
| Agent | Description |
|
CASAN bridge không gọi model lần thứ hai. Claude Code/Codex vẫn là model
|
||||||
|-------|-------------|
|
executor duy nhất.
|
||||||
| `speckit.constitution` | Define project principles and constraints |
|
|
||||||
| `speckit.specify` | Convert requirements into feature specification (`spec.md`) |
|
|
||||||
| `speckit.clarify` | Resolve ambiguous requirements (no pause) |
|
|
||||||
| `speckit.plan` | Create implementation plan (`plan.md` + data-model + contracts) |
|
|
||||||
| `speckit.tasks` | Generate task list (`tasks.md`) |
|
|
||||||
| `speckit.implement` | Implementation with auto build & fix |
|
|
||||||
| `speckit.analyze` | Cross-artifact consistency and quality analysis |
|
|
||||||
| `speckit.checklist` | Generate custom quality checklists |
|
|
||||||
| `speckit.taskstoissues` | Convert tasks to GitHub issues |
|
|
||||||
|
|
||||||
### FPT-Defined Agents (IPA Gen + Review + Orchestrator + Test)
|
## Client support
|
||||||
|
|
||||||
| Agent | Description |
|
| Client | Chat bình thường tự qua CASAN | Bước bắt buộc |
|
||||||
|-------|-------------|
|
|---|---:|---|
|
||||||
| `casan.pipeline` | **Optional reference orchestrator** — runs the bundled 13-step Spec-Kit + IPA flow |
|
| Claude Code CLI/extension | Có | Mở repository dưới dạng trusted project |
|
||||||
| `casan.srs` | Generate SRS (ソフトウェア要件定義書) per module → `docs/output/ipa-docs/` |
|
| Codex CLI/extension | Có | Mở `/hooks`, review và trust hook hash |
|
||||||
| `casan.bd` | Generate BD / 外部設計 (Basic Design) per module → `docs/output/ipa-docs/` |
|
| GitHub Copilot Chat | Không | Cài CASAN VSIX và gửi `@casan <prompt>` |
|
||||||
| `casan.dd` | Generate DD / 内部設計 (Detail Design) per module → `docs/output/ipa-docs/` |
|
|
||||||
| `casan.srs` | Generate system-wide SRS (one-time, pre-flow) → `docs/output/srs-systems/` |
|
|
||||||
| `casan.reviewspec` | **Review** — validate `spec.md` quality and completeness |
|
|
||||||
| `casan.reviewplan` | **Review** — validate `plan.md` conformance to spec |
|
|
||||||
| `casan.reviewcode` | **Review** — code review + DB data check |
|
|
||||||
| `casan.testkit` | **Test** — generate test cases from SRS + BD + DD; run automated tests |
|
|
||||||
| `Flow-Agent` | General-purpose flow agent |
|
|
||||||
|
|
||||||
---
|
GitHub Copilot không cung cấp public API để extension intercept toàn bộ built-in
|
||||||
|
chat. Chỉ route explicit `@casan` mới là CASAN-owned. Một backend tự gọi LLM API
|
||||||
|
cũng không đi qua IDE hooks và cần adapter riêng.
|
||||||
|
|
||||||
## AI-SDLC Usage Guide
|
## Kiến trúc runtime
|
||||||
|
|
||||||
1. **Adopt governance**: Run `casan init`, select the IDE clients, complete any trust/VSIX onboarding, then run `casan doctor`.
|
```mermaid
|
||||||
2. **Continue the project workflow**: Use the project's existing commands, agents, skills, review loops, and source layout normally. CASAN does not require a fixed number of steps.
|
flowchart TB
|
||||||
3. **Optional reference flow**: Only when the project intentionally adopts the bundled Spec-Kit + IPA workflow, prepare input under `apps/<project-id>/domain/input/`, configure the constitution, optionally generate the system SRS, then invoke `casan.pipeline`.
|
U["Developer"] --> C1["Claude Code"]
|
||||||
4. **Reference-flow output**:
|
U --> C2["Codex"]
|
||||||
- `docs/output/ipa-docs/` — IPA design documents (SRS, BD, DD, Test Cases)
|
U --> C3["VS Code: @casan"]
|
||||||
- `docs/output/output_logs/` — AI agent execution logs
|
|
||||||
- `docs/output/srs-systems/` — System-wide SRS (generated once)
|
|
||||||
- `specs/[FEATURE_NAME]/` — Spec-Kit artifacts (`spec.md`, `plan.md`, `tasks.md`, etc.)
|
|
||||||
- Source code remains in the locations defined by the adopted project
|
|
||||||
|
|
||||||
---
|
C1 --> E1["Project hook events"]
|
||||||
|
C2 --> E1
|
||||||
|
C3 --> E2["CASAN-owned VSIX route"]
|
||||||
|
|
||||||
## Directory Structure
|
E1 --> B[".casan/casan-hook.py"]
|
||||||
|
E2 --> B
|
||||||
|
B --> V{"Global harness<br/>matches version.lock?"}
|
||||||
|
V -- "No" --> D["Deny or degrade<br/>according to mode"]
|
||||||
|
V -- "Yes" --> A["Client adapter"]
|
||||||
|
A --> G["Agentic bridge"]
|
||||||
|
|
||||||
```
|
subgraph TURN["Per-turn lifecycle"]
|
||||||
├── .claude/
|
direction LR
|
||||||
│ ├── agents/ # All agent definitions (subagents)
|
L1["Admission<br/>H1 + H4"] --> L2["Pre-tool gate<br/>H2 + H4"]
|
||||||
│ │ ├── casan.pipeline.md # Optional reference orchestrator agent
|
L2 --> L3["Post-tool evidence<br/>H5"]
|
||||||
│ │ ├── speckit.*.md # Spec-Kit agents (specify, clarify, plan, tasks, implement, analyze, checklist, taskstoissues)
|
L3 --> L4["Finalize<br/>H3 + H5 + H6 + H7"]
|
||||||
│ │ ├── casan.*.md # Reusable CASAN agents (srs, bd, dd, reviews, testkit, pipeline)
|
end
|
||||||
│ │ ├── protocols/ # Shared protocols (auto-resolve, gate-retry, logging, pipeline-context, etc.)
|
|
||||||
│ │ ├── steps/ # Step definitions for orchestrator (steps-01-04, steps-05-07, etc.)
|
G --> L1
|
||||||
│ │ └── templates/ # Agent output templates (pipeline-completion, report-templates)
|
L4 --> S["Project runtime state<br/>.specify/logs + state"]
|
||||||
│ └── commands/ # Claude Code slash commands
|
L4 --> R["Native client result"]
|
||||||
│ ├── casan.pipeline.md # Run optional reference pipeline
|
|
||||||
│ ├── speckit.*.md # Spec-Kit slash commands
|
|
||||||
│ └── casan.*.md # Reusable CASAN commands
|
|
||||||
│
|
|
||||||
├── CLAUDE.md # Global Claude Code project instructions
|
|
||||||
│
|
|
||||||
├── .specify/ # SpecKit configuration and templates
|
|
||||||
│ ├── init-options.json # Initialization options
|
|
||||||
│ ├── memory/
|
|
||||||
│ │ └── constitution.md # Project-wide principles and constraints
|
|
||||||
│ ├── scripts/ # Utility scripts
|
|
||||||
│ │ ├── bash/ # Bash scripts
|
|
||||||
│ │ └── powershell/ # PowerShell scripts
|
|
||||||
│ └── templates/
|
|
||||||
│ ├── agent-file-template.md # Agent definition template
|
|
||||||
│ ├── checklist-template.md # Quality checklist template
|
|
||||||
│ ├── constitution-template.md
|
|
||||||
│ ├── spec-template.md # Spec-Kit templates
|
|
||||||
│ ├── plan-template.md
|
|
||||||
│ ├── tasks-template.md
|
|
||||||
│ ├── srs-template.md # IPA templates (SRS, BD, DD)
|
|
||||||
│ ├── bd-ipa-template.md
|
|
||||||
│ └── dd-ipa-template.md
|
|
||||||
│
|
|
||||||
├── apps/
|
|
||||||
│ └── <project-id>/domain/ # Per-project CASAN domain pack
|
|
||||||
│ ├── input/
|
|
||||||
│ │ ├── requirement.md # Project requirements
|
|
||||||
│ │ └── architecture.md # Architecture and constraints
|
|
||||||
│ ├── corpus/ # Benign/red-team evaluation corpus
|
|
||||||
│ ├── golden-runs/ # Golden outputs for drift checks
|
|
||||||
│ └── traceability-map.json
|
|
||||||
│
|
|
||||||
├── docs/
|
|
||||||
│ └── output/ # Output of the AI-SDLC process
|
|
||||||
│ ├── ipa-docs/ # IPA documents
|
|
||||||
│ │ ├── srs/ # SRS documents per module
|
|
||||||
│ │ ├── bd/ # BD documents per module
|
|
||||||
│ │ ├── dd/ # DD documents per module
|
|
||||||
│ │ ├── testcase/ # Test case documents per module
|
|
||||||
│ │ └── testreport/ # Test report documents per module
|
|
||||||
│ ├── output_logs/ # AI agent execution logs (per feature)
|
|
||||||
│ └── srs-systems/ # System-wide SRS (generated once, pre-flow)
|
|
||||||
│
|
|
||||||
├── specs/ # Optional Spec-Kit feature artifacts
|
|
||||||
├── <existing-source-directories>/ # Project-owned; CASAN init preserves them
|
|
||||||
└── <existing-ci-and-tooling>/ # Project-owned; CASAN init preserves them
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Directory Details
|
## Cấu trúc cài đặt thực tế
|
||||||
|
|
||||||
#### `.claude/agents/`
|
CASAN dùng mô hình hybrid: policy code nằm ở global installation; project chỉ
|
||||||
Contains all agent definition files used by Claude Code. This includes both **Spec-Kit agents** (core flow: `speckit.specify`, `speckit.clarify`, `speckit.plan`, `speckit.tasks`, `speckit.implement`, plus utility agents `speckit.analyze`, `speckit.checklist`, `speckit.taskstoissues`) and reusable **CASAN agents** (`casan.*`):
|
giữ bootstrap, pin và state riêng.
|
||||||
- **IPA Doc Gen agents** — `casan.srs`, `casan.bd`, `casan.dd`: generate IPA-standard design documents (SRS, BD, DD) per module, output to `docs/output/ipa-docs/`.
|
|
||||||
- **Review agents** — `casan.reviewspec`, `casan.reviewplan`, `casan.reviewcode`: validate the quality of Spec-Kit artifacts (`spec.md`, `plan.md`, source code) with auto-retry loops.
|
|
||||||
- **Optional reference orchestrator** — `casan.pipeline`: runs the bundled
|
|
||||||
13-step Spec-Kit + IPA flow when a project explicitly chooses that workflow.
|
|
||||||
- **Test agent** — `casan.testkit`: generates test cases from SRS + BD + DD and executes automated tests (Jest / Playwright).
|
|
||||||
- **Subdirectories** — `protocols/` (shared protocols for auto-resolve, gate-retry, logging, etc.), `steps/` (orchestrator step definitions), `templates/` (output report templates).
|
|
||||||
|
|
||||||
#### `.claude/commands/`
|
```mermaid
|
||||||
Claude Code slash commands that invoke the corresponding agents. A project may
|
flowchart TB
|
||||||
use its own commands normally; `/casan.pipeline` is only for triggering the
|
subgraph M["Developer machine"]
|
||||||
optional bundled reference pipeline.
|
H["CASAN_HOME"]
|
||||||
|
CUR["current<br/>symlink hoặc junction"]
|
||||||
|
VER["versions/<version>"]
|
||||||
|
CLI["bin/casan"]
|
||||||
|
HAR["packages/casan-harness"]
|
||||||
|
DEV["packages/casan-devkit"]
|
||||||
|
|
||||||
#### `.specify/`
|
H --> CUR --> VER
|
||||||
Spec-Kit configuration directory. Stores project-wide principles, scripts, and all templates:
|
H --> CLI
|
||||||
- **`init-options.json`** — Initialization options for Spec-Kit setup.
|
VER --> HAR
|
||||||
- **`memory/constitution.md`** — The project constitution: shared principles, constraints, and conventions that apply to every feature across the entire project.
|
VER --> DEV
|
||||||
- **`scripts/`** — Utility scripts in `bash/` and `powershell/` for automation tasks.
|
end
|
||||||
- **`templates/`** — Format templates used by agents to generate artifacts. Includes Spec-Kit templates (`spec-template.md`, `plan-template.md`, `tasks-template.md`, `constitution-template.md`, `checklist-template.md`, `agent-file-template.md`) and IPA templates (`srs-template.md`, `bd-ipa-template.md`, `dd-ipa-template.md`).
|
|
||||||
|
|
||||||
#### `apps/<project-id>/domain/input/`
|
INIT["casan init"] --> CFG
|
||||||
Per-project requirements and architecture used by CASAN gates and traceability.
|
CLI --> INIT
|
||||||
The L2 initializer creates missing domain-pack files without overwriting existing
|
DEV --> INIT
|
||||||
project content.
|
|
||||||
|
|
||||||
#### `docs/output/`
|
subgraph P["Existing project"]
|
||||||
All artifacts produced by the AI-SDLC process:
|
CFG[".casan/<br/>config.json<br/>version.lock<br/>agentic.env<br/>init-manifest.json"]
|
||||||
- **`ipa-docs/`** — IPA design documents organized in subdirectories: `srs/`, `bd/`, `dd/`, `testcase/`, `testreport/`. Generated by `casan.srs`, `casan.bd`, `casan.dd`, and `casan.testkit`. Each subdirectory contains per-module documents.
|
BOOT[".casan/casan-hook.py"]
|
||||||
- **`output_logs/`** — Execution logs from AI agents organized per feature (e.g., `000-system-srs/`, `001-access-authentication/`, etc.), useful for debugging and auditing the generation process.
|
STATE[".specify/<br/>logs/<br/>state/<br/>.gitignore"]
|
||||||
- **`srs-systems/`** — System-wide SRS generated once at the beginning by `casan.srs`. Contains per-module SRS overviews (`mod01-access-authentication/`, `mod02-workspace-dashboard/`, etc.) plus `srs-overview-system.md`. Not part of the optional reference pipeline steps.
|
CLIENTS["Client config khi được chọn<br/>.claude/settings.json<br/>.codex/hooks.json<br/>.vscode/extensions.json"]
|
||||||
|
L2["Level 2 only<br/>.gitea/workflows/casan-ci.yml<br/>apps/<project-id>/domain/"]
|
||||||
|
OWNED["Project-owned<br/>source, agents, skills,<br/>commands, hooks và CI khác"]
|
||||||
|
end
|
||||||
|
|
||||||
#### `specs/`
|
INIT --> BOOT
|
||||||
|
INIT --> STATE
|
||||||
|
INIT --> CLIENTS
|
||||||
|
INIT -. "chỉ khi --level devkit" .-> L2
|
||||||
|
INIT -. "không thay đổi" .-> OWNED
|
||||||
|
CFG --> BOOT
|
||||||
|
HAR -. "runtime policy" .-> BOOT
|
||||||
|
```
|
||||||
|
|
||||||
Each folder contains `spec.md`, `plan.md`, `tasks.md`, `checklists/`, and `contracts/`. This directory serves as the **knowledge base** for agents.
|
### File nào được thay đổi
|
||||||
|
|
||||||
#### Source Code
|
| Path | Hành vi |
|
||||||
CASAN does not prescribe NestJS, React, Java, .NET, or any other application
|
|---|---|
|
||||||
stack. Existing source, CI, `.claude`, `.github`, agents, skills, prompts, and
|
| `.casan/config.json` | Lưu project id, mode và danh sách client |
|
||||||
project instructions remain project-owned. Hybrid init only adds or merges the
|
| `.casan/version.lock` | Pin version và SHA-256 của global harness |
|
||||||
CASAN integration files documented above.
|
| `.casan/casan-hook.py` | Bootstrap stdlib, verify pin rồi dispatch adapter |
|
||||||
|
| `.casan/agentic.env` | Compatibility/reference flags; runtime đọc `config.json` |
|
||||||
|
| `.casan/init-manifest.json` | Ghi file đã tạo và backup |
|
||||||
|
| `.specify/logs`, `.specify/state` | Runtime trace, audit và state; không commit |
|
||||||
|
| `.claude/settings.json` | Merge CASAN handlers khi enable Claude |
|
||||||
|
| `.codex/hooks.json` | Merge CASAN handlers khi enable Codex |
|
||||||
|
| `.vscode/extensions.json` | Merge extension recommendations theo client |
|
||||||
|
| `.gitea/workflows/casan-ci.yml` | Chỉ Level 2, chỉ tạo khi chưa có |
|
||||||
|
| `apps/<project-id>/domain/` | Chỉ Level 2, chỉ bổ sung file còn thiếu |
|
||||||
|
|
||||||
|
Trước lần thay đổi đầu tiên, init tạo backup `<file>.casan-bak` cho file hiện
|
||||||
|
hữu. `init-manifest.json` ghi lại các file và backup liên quan.
|
||||||
|
|
||||||
|
### Nội dung luôn được giữ nguyên
|
||||||
|
|
||||||
|
- Source code và cấu trúc ứng dụng.
|
||||||
|
- `.claude/agents`, `.claude/skills`, `.claude/commands`.
|
||||||
|
- Agents, skills, prompts và instructions trong `.github/`.
|
||||||
|
- Hook và JSON key không thuộc CASAN.
|
||||||
|
- CI/workflow hiện hữu.
|
||||||
|
- Vendored `packages/casan-harness` của project cũ; chỉ xóa sau khi đã migration
|
||||||
|
toàn bộ CI và scripts sang global harness.
|
||||||
|
|
||||||
|
Nếu target chính là CASAN source hub, init từ chối để tránh self-adoption. Không
|
||||||
|
dùng `--force` trừ khi chủ động muốn kiểm thử trường hợp này.
|
||||||
|
|
||||||
|
## Chọn mode
|
||||||
|
|
||||||
|
| Mode | Dùng cho | Certification |
|
||||||
|
|---|---|---|
|
||||||
|
| `enforce` | Mặc định production | Side effect fail-closed; turn đủ evidence có thể certified |
|
||||||
|
| `observe` | Pilot và thu telemetry | Không chặn như production; luôn `observed_only` |
|
||||||
|
|
||||||
|
```bash
|
||||||
|
casan init --level core --client claude,codex --mode enforce
|
||||||
|
```
|
||||||
|
|
||||||
|
Không gọi một turn là CASAN-certified nếu không có trace tương ứng hoặc trace bị
|
||||||
|
đánh dấu `observed_only`/`non_certified`.
|
||||||
|
|
||||||
|
## Kiểm tra, cấu hình lại và nâng cấp
|
||||||
|
|
||||||
|
Kiểm tra project:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
casan doctor
|
||||||
|
casan verify-harness
|
||||||
|
casan level show
|
||||||
|
```
|
||||||
|
|
||||||
|
- `doctor`: kiểm tra config, bootstrap, hook schema, adapter smoke test, VSIX và
|
||||||
|
cảnh báo trust.
|
||||||
|
- `verify-harness`: tính lại live hash và so với project pin; drift trả exit
|
||||||
|
code `3`.
|
||||||
|
- `level show`: hiển thị package level đã cài và target level của project.
|
||||||
|
|
||||||
|
Đổi danh sách client bằng cách chạy lại init với **toàn bộ danh sách mong muốn**.
|
||||||
|
CASAN handler của client bị bỏ khỏi danh sách sẽ được gỡ, còn hook khác được giữ:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
casan init --level core --client claude
|
||||||
|
|
||||||
|
# Tắt toàn bộ IDE integration của CASAN nhưng giữ config/state
|
||||||
|
casan init --level core --client none
|
||||||
|
```
|
||||||
|
|
||||||
|
`--client none` không uninstall VSIX đã cài trên máy; nếu không còn dùng route
|
||||||
|
`@casan`, gỡ extension `fpt-casan.casan-governed-chat` trong VS Code.
|
||||||
|
|
||||||
|
Khi nâng cấp CASAN:
|
||||||
|
|
||||||
|
1. Chạy lại installer từ release đã duyệt.
|
||||||
|
2. Chạy lại `casan init` trong từng project để cập nhật bootstrap và pin.
|
||||||
|
3. Chạy `casan doctor` và `casan verify-harness`.
|
||||||
|
4. Với Codex, review/trust lại hook nếu hash thay đổi.
|
||||||
|
|
||||||
|
Trong production, không bỏ qua `HARNESS_INTEGRITY_DRIFT`.
|
||||||
|
|
||||||
|
## CI
|
||||||
|
|
||||||
|
Runner phải cài cùng release CASAN mà project đã pin. Gate tối thiểu:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
casan verify-harness
|
||||||
|
casan gate
|
||||||
|
```
|
||||||
|
|
||||||
|
Level 2 tạo `.gitea/workflows/casan-ci.yml` như một template nếu file chưa tồn
|
||||||
|
tại. Template phải được review theo runner và mô hình cài đặt của tổ chức trước
|
||||||
|
khi enable; CASAN không ghi đè workflow hiện hữu.
|
||||||
|
|
||||||
|
Đảm bảo `.specify/logs/` và `.specify/state/` không được commit. Init chỉ tạo
|
||||||
|
`.specify/.gitignore` khi file đó chưa tồn tại.
|
||||||
|
|
||||||
|
## Cấu trúc source repository CASAN
|
||||||
|
|
||||||
|
| Path | Trách nhiệm |
|
||||||
|
|---|---|
|
||||||
|
| `bin/casan` | CLI entrypoint |
|
||||||
|
| `install.sh`, `install.ps1` | Global installers |
|
||||||
|
| `packages/casan-harness/` | Runtime controls, adapters, policies, evidence và tests |
|
||||||
|
| `packages/casan-devkit/` | Hybrid adoption, project bootstrap và templates |
|
||||||
|
| `packages/casan-control-panel/` | Platform UI/API preview, deploy riêng |
|
||||||
|
| `packaging/levels.json` | Nguồn sự thật cho package level và maturity |
|
||||||
|
| `infra/` | Local/production deployment references |
|
||||||
|
| `docs/` | Security, operations, packaging và design records |
|
||||||
|
| `apps/` | Demo/validation applications; không phải runtime dependency của `casan init` |
|
||||||
|
|
||||||
|
## Tài liệu chi tiết
|
||||||
|
|
||||||
|
- [Hybrid installation và migration](docs/casan/CASAN_INSTALL_HYBRID.md)
|
||||||
|
- [Agentic client security boundary](docs/casan/CASAN_AGENTIC_CLIENT_SECURITY.md)
|
||||||
|
- [Windows client setup](docs/casan/CASAN_AGENTIC_CLIENTS_WINDOWS.md)
|
||||||
|
- [Packaging levels](docs/packaging/CASAN_PACKAGING_PLAN.md)
|
||||||
|
- [Production infrastructure](infra/production/README.md)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Xem [LICENSE](LICENSE).
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
flowchart TB
|
||||||
|
U["Developer"] --> C1["Claude Code"]
|
||||||
|
U --> C2["Codex"]
|
||||||
|
U --> C3["VS Code: @casan"]
|
||||||
|
|
||||||
|
C1 --> E1["Project hook events"]
|
||||||
|
C2 --> E1
|
||||||
|
C3 --> E2["CASAN-owned VSIX route"]
|
||||||
|
|
||||||
|
E1 --> B[".casan/casan-hook.py"]
|
||||||
|
E2 --> B
|
||||||
|
B --> V{"Global harness<br/>matches version.lock?"}
|
||||||
|
V -- "No" --> D["Deny or degrade<br/>according to mode"]
|
||||||
|
V -- "Yes" --> A["Client adapter"]
|
||||||
|
A --> G["Agentic bridge"]
|
||||||
|
|
||||||
|
subgraph TURN["Per-turn lifecycle"]
|
||||||
|
direction LR
|
||||||
|
L1["Admission<br/>H1 + H4"] --> L2["Pre-tool gate<br/>H2 + H4"]
|
||||||
|
L2 --> L3["Post-tool evidence<br/>H5"]
|
||||||
|
L3 --> L4["Finalize<br/>H3 + H5 + H6 + H7"]
|
||||||
|
end
|
||||||
|
|
||||||
|
G --> L1
|
||||||
|
L4 --> S["Project runtime state<br/>.specify/logs + state"]
|
||||||
|
L4 --> R["Native client result"]
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 36 KiB |
@@ -0,0 +1,35 @@
|
|||||||
|
flowchart TB
|
||||||
|
subgraph M["Developer machine"]
|
||||||
|
H["CASAN_HOME"]
|
||||||
|
CUR["current<br/>symlink hoặc junction"]
|
||||||
|
VER["versions/<version>"]
|
||||||
|
CLI["bin/casan"]
|
||||||
|
HAR["packages/casan-harness"]
|
||||||
|
DEV["packages/casan-devkit"]
|
||||||
|
|
||||||
|
H --> CUR --> VER
|
||||||
|
H --> CLI
|
||||||
|
VER --> HAR
|
||||||
|
VER --> DEV
|
||||||
|
end
|
||||||
|
|
||||||
|
INIT["casan init"] --> CFG
|
||||||
|
CLI --> INIT
|
||||||
|
DEV --> INIT
|
||||||
|
|
||||||
|
subgraph P["Existing project"]
|
||||||
|
CFG[".casan/<br/>config.json<br/>version.lock<br/>agentic.env<br/>init-manifest.json"]
|
||||||
|
BOOT[".casan/casan-hook.py"]
|
||||||
|
STATE[".specify/<br/>logs/<br/>state/<br/>.gitignore"]
|
||||||
|
CLIENTS["Client config khi được chọn<br/>.claude/settings.json<br/>.codex/hooks.json<br/>.vscode/extensions.json"]
|
||||||
|
L2["Level 2 only<br/>.gitea/workflows/casan-ci.yml<br/>apps/<project-id>/domain/"]
|
||||||
|
OWNED["Project-owned<br/>source, agents, skills,<br/>commands, hooks và CI khác"]
|
||||||
|
end
|
||||||
|
|
||||||
|
INIT --> BOOT
|
||||||
|
INIT --> STATE
|
||||||
|
INIT --> CLIENTS
|
||||||
|
INIT -. "chỉ khi --level devkit" .-> L2
|
||||||
|
INIT -. "không thay đổi" .-> OWNED
|
||||||
|
CFG --> BOOT
|
||||||
|
HAR -. "runtime policy" .-> BOOT
|
||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 33 KiB |
Reference in New Issue
Block a user