Skip to main content

decision-logging

Defines when and how commands must log architecture decisions to _state.json decisions[] for auditability

インストールへ移動

ソース情報

リポジトリ
navraj007in/architecture-cowork-plugin
ソースの最終更新活動
2026年7月8日 10:04
検出された SKILL.md の言語
英語
スター
2
フォーク
1

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
decision-logging
description
Defines when and how commands must log architecture decisions to _state.json decisions[] for auditability
# Decision Logging Skill When commands make architecture decisions (choosing tech stacks, patterns, frameworks, databases, etc.), they MUST log those decisions to `_state.json.decisions[]` for auditability and future reference. ## When to Log a Decision Log a decision whenever your command: 1. **Chooses a technology** (database, framework, language, messaging system, auth provider) 2. **Selects an architectural pattern** (monolith vs. microservices, clean vs. modular, etc.) 3. **Determines a trade-off** (prioritize cost over latency, scalability over simplicity, etc.) 4. **Makes a significant strategic choice** that affects the system's design **Do NOT log:** - Routine operations (generating files, running tests) - Configuration of already-decided technologies - Re-running previous decisions **Examples of decisions to log:** - ✅ "Choose PostgreSQL for primary database" (blueprint command) - ✅ "Use React over Vue for UI framework" (scaffold command) - ✅ "Prioritize fast iteration over peak performance" (mvp-scope) - ✅ "Use monolithic architecture for initial MVP" (architecture design) - ❌ "Generated auth routes file" (implementation detail, not decision) - ❌ "Installed dependencies" (mechanical task, not decision) ## Decision Structure Each decision is a JSON object in the `decisions[]` array: ```json { "id": "D-NNN", "title": "Choose PostgreSQL for primary database", "rationale": "ACID compliance for order consistency. Team has PostgreSQL expertise. Query flexibility for future analytics features.", "alternatives_rejected": [ "MongoDB (weak multi-document transactions, overkill for relational data)", "DynamoDB (cost scales poorly with joins, limited query flexibility)" ], "trade_offs": "Higher operational complexity than managed cloud DBs. Team must maintain backups. Cold-start slower than serverless options.", "made_by_command": "blueprint", "timestamp": "2026-04-24T14:32:10Z" } ``` ### Field Details | Field | Type | Required | Description | |-------|------|----------|-------------| | `id` | string | Yes | Unique decision ID (e.g., `"D-001"`, `"D-002"`). Increment sequentially within a project. | | `title` | string | Yes | Brief decision title (3-10 words). E.g., `"PostgreSQL for primary database"` | | `rationale` | string | Yes | Why this choice? What does it enable? What problem does it solve? (2-5 sentences or bullets) | | `alternatives_rejected` | array of strings | Yes | What were the runner-up options and why did they lose? Makes future reconsideration easier. At least 2 alternatives. | | `trade_offs` | string | Yes | What are you giving up? What becomes harder or more expensive? (1-3 sentences) | | `made_by_command` | string | Yes | Which command made this decision? (e.g., `"blueprint"`, `"sdl"`, `"scaffold"`) | | `timestamp` | string | Yes | ISO-8601 timestamp when decision was made (e.g., `"2026-04-24T14:32:10Z"`) | ## How Commands Log Decisions ### Pattern: Read → Decide → Log ```pseudo 1. Read current _state.json (if exists) 2. Read SDL and extract/determine tech choices 3. For each decision (e.g., database choice): a. Create decision object with all 7 fields b. Append to _state.json.decisions[] array 4. Write _state.json back to disk ``` ### Code Example: Python/JavaScript ```python # Read existing state import json from datetime import datetime state = json.load(open('architecture-output/_state.json')) if os.path.exists(...) else {"decisions": []} # Make a decision new_decision = { "id": f"D-{len(state.get('decisions', [])) + 1:03d}", "title": "PostgreSQL for primary database", "rationale": "ACID compliance for order consistency. Team has expertise. Query flexibility for analytics.", "alternatives_rejected": [ "MongoDB (weak transactions, overkill for relational data)", "DynamoDB (cost scales poorly, limited queries)" ], "trade_offs": "Higher ops complexity. Team maintains backups. Cold-start slower than serverless.", "made_by_command": "blueprint", "timestamp": datetime.utcnow().isoformat() + "Z" } # Append to decisions array state.setdefault("decisions", []).append(new_decision) # Write back json.dump(state, open('architecture-output/_state.json', 'w')) ``` ```javascript // JavaScript equivalent const fs = require('fs'); const path = require('path'); const stateFile = 'architecture-output/_state.json'; const state = fs.existsSync(stateFile) ? JSON.parse(fs.readFileSync(stateFile, 'utf8')) : { decisions: [] }; const newDecision = { id: `D-${String(state.decisions.length + 1).padStart(3, '0')}`, title: "PostgreSQL for primary database", rationale: "ACID compliance for order consistency. Team has expertise. Query flexibility for analytics.", alternatives_rejected: [ "MongoDB (weak transactions, overkill for relational data)", "DynamoDB (cost scales poorly, limited queries)" ], trade_offs: "Higher ops complexity. Team maintains backups. Cold-start slower than serverless.", made_by_command: "blueprint", timestamp: new Date().toISOString().replace('Z', 'Z') // Ensure Z suffix }; state.decisions.push(newDecision); fs.writeFileSync(stateFile, JSON.stringify(state, null, 2)); ``` ## Decision ID Sequence Decision IDs are per-project (not global). Start at `D-001` for the first decision: - First decision by blueprint: `D-001` - Second decision by blueprint: `D-002` - First decision by scaffold command: `D-003` (continues sequence, not restart) ID format: `D-NNN` where NNN is zero-padded 3-digit number. ## Multiple Decisions Per Command If your command makes multiple decisions, create one object per decision: ```json { "decisions": [ { "id": "D-001", "title": "PostgreSQL for primary database", "rationale": "...", "alternatives_rejected": ["..."], "trade_offs": "...", "made_by_command": "blueprint", "timestamp": "2026-04-24T14:32:10Z" }, { "id": "D-002", "title": "React for frontend framework", "rationale": "...", "alternatives_rejected": ["..."], "trade_offs": "...", "made_by_command": "blueprint", "timestamp": "2026-04-24T14:32:15Z" } ] } ``` Each decision gets its own ID and timestamp (even if made seconds apart). ## Linking Decisions to ADRs (Phase 1.5+) When ADRs are generated, they should reference decision IDs: ```markdown # ADR-001: Database Choice **Decision ID:** D-001 ## Status Accepted ## Context [Rationale from decisions[0].rationale] ## Decision PostgreSQL ## Consequences [Trade-offs from decisions[0].trade_offs] ## Alternatives Considered - MongoDB: [from decisions[0].alternatives_rejected[0]] - DynamoDB: [from decisions[0].alternatives_rejected[1]] ``` ## Viewing & Analyzing Decisions Users can analyze decisions via: 1. **Manual review:** `jq '.decisions' architecture-output/_state.json` 2. **Decision report:** `/architect:decisions-linked` (Phase 1.5 command) generates markdown mapping decisions to ADRs 3. **Check-state command:** `/architect:check-state` validates decision logging compliance ## Best Practices 1. **Be specific:** "PostgreSQL" not "choose a database" 2. **Capture rationale:** Explain WHY, not just WHAT 3. **List real alternatives:** Don't strawman rejected options; explain their actual merits 4. **Quantify trade-offs:** "5x higher ops complexity", "30% cost increase", not vague 5. **Timestamp accurately:** Use actual decision time, not file generation time 6. **One per decision:** Don't lump unrelated choices into one decision object 7. **Made_by_command:** Always set; helps trace where decision came from ## Related Commands - `/architect:check-state` — Validates decisions array - `/architect:decisions-linked` (Phase 1.5) — Maps decisions to ADRs - `/architect:generate-docs` — Includes decision log in documentation ## Example Decisions from Real Projects ### E-commerce SaaS ```json { "id": "D-001", "title": "Next.js App Router for frontend", "rationale": "Server components reduce client-side complexity. File-based routing matches team's experience. Excellent TypeScript support.", "alternatives_rejected": [ "React SPA + Express (more configuration, fewer conventions)", "Remix (smaller ecosystem, steeper learning curve)" ], "trade_offs": "Tied to Vercel deployment for optimal performance. Vendor lock-in risk.", "made_by_command": "blueprint", "timestamp": "2026-04-24T10:00:00Z" } ``` ### Startup MVP ```json { "id": "D-001", "title": "Monolithic architecture for MVP", "rationale": "Faster time-to-market. Simpler deployment. Team of 2 engineers. Can split to microservices later if needed.", "alternatives_rejected": [ "Microservices (overkill complexity for MVP, ops overhead)", "Serverless (unpredictable cold starts for user-facing APIs)" ], "trade_offs": "Will need refactoring when scaling to 10+ services. Single point of failure. Database scaling limited.", "made_by_command": "blueprint", "timestamp": "2026-04-20T14:32:10Z" } ``` ## Not Logging Is Not OK If your command makes a tech choice but doesn't log it: - Future teams don't understand why the choice was made - Second-guessing common (why Postgres? why not Mongo?) - ADRs can't be linked to decisions - `/architect:check-state` may flag missing decisions - Institutional knowledge is lost when team member leaves **Always log decisions. It's cheap, and it pays dividends.**
GitHubで見る