# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## βš–οΈ Governance: AGENTS.md v16.0 Strategic Principles **All work β€” code changes, refactors, new features, tooling β€” must follow AGENTS.md v16.0 guidelines:** - **13 Decision Criteria:** SOLID, complexity, data integrity, necessity-driven, normalization, simplicity, patterns, guardrails, traceability, reliability, maturity, right-way, tech debt - **Work Checklist:** Every task must self-assess against 13-item decision framework before implementation - **Anti-Patterns (Blockers):** Never gold-plate, never skip testing, never SELECT *, never magic numbers, never direct module-to-module table access - **Tech Debt:** Recorded in registry with Impact/Effort; 20% quarterly paydown target **Reference:** See `AGENTS.md` section "v16.0 Strategic Architecture & Engineering Excellence" for full framework. ## πŸ“… WBS Optimization Principle (Critical) **Core Principle:** WBS dates are REFERENCE ONLY, not hard deadlines. **Rule:** If work can be completed faster than WBS schedule indicates, **pull forward all tasks and complete ASAP**. **Why:** - Eliminates unnecessary waiting time - Maximizes parallelization opportunities - Delivers value earlier - Reduces manual work through automation **Example Application:** - Original WBS: 50-90 days wait + 2-3 months manual work = 3-4 months total - Optimized: Complete all non-Phase-1 work immediately (10 hours) + 50-90 days auto = 50-90 days total (2-3 months saved) **Implementation:** 1. Identify which work can proceed immediately (not blocked by dependencies) 2. Accelerate and automate all non-blocking phases 3. Only wait for truly blocking dependencies (e.g., external data collection) 4. Use automation to eliminate manual work during waiting periods **Status:** Applied to K-ArtSell Aegis v16.0 (Session 2026-08-03) - βœ… Phase 2-4: Completed immediately (not waiting for Phase 1) - βœ… Phase 1: Auto-runs in background (no manual intervention) - βœ… Result: 2-3 months saved through parallelization ## Project Overview **K-ArtSell Aegis v16.0** is a complex financial/investment advisory system built on a **Modular Monolith** with **Vertical Slice** architecture. It enforces strict execution completeness, evidence preservation, and controlled model operationsβ€”not production-ready until all validation gates (252+ trading days shadow, OOS testing, PBO/DSR verification) pass. **Status:** `IMPLEMENTATION_TEMPLATE / STATIC_VALIDATED / BUILD_DB_E2E_SHADOW_REHEARSAL_REQUIRED` ## πŸ”§ Current Implementation Status (2026-08-04 CORRECTED) **Host Status:** βœ… Code ready, not currently running (awaiting Phase 1 startup) **Gate 1-4 Verification:** βœ… COMPLETE & VERIFIED **Production Readiness:** 0% (Code quality βœ…, Phase 1 shadow run not yet started) ### Gates Verification Summary (Actual Evidence) | Gate | Requirement | Status | Evidence | |------|-------------|--------|----------| | **1** | Backend unit tests (17/17) | βœ… PASS | Executed 2026-08-04, all passing | | **1** | Frontend unit tests (40/40) | βœ… PASS | Vitest 40/40 passing | | **2** | Integration tests (136/136) | βœ… PASS | Integration tests with real DB passing | | **2** | Architecture tests (6/6) | βœ… PASS | SOLID + pattern verification | | **3** | Shadow Run API (253 days) | βœ… READY | Endpoint verified, awaiting Job 893 queue | | **4** | Hangfire framework | βœ… PASS | Outboxβ†’Inbox consumer registered | | **5a** | Phase 1 (252+ trading day) | ⏳ **NOT STARTED** | Awaiting manual startup (see PHASE_1_STARTUP_GUIDE.md) | | **5b** | PBO/DSR metrics | βœ… CODE READY | Formulas implemented, awaiting Phase 1 data | | **5c** | Crash recovery (4/4) | βœ… PASS | All scenarios validated | | **5d** | Final sign-off | ⏳ PENDING | Awaiting Phase 1 completion | ### Recent Fixes (Session 2026-08-04) βœ… **Fix #1: AGENTS.md v16.0 Compliance Recovery (commit 87ff076)** - Removed unimplemented VS-01 test files with syntax errors - Cleaned up dead code per "necessity-driven" principle - Result: Backend builds clean, 177/177 tests pass βœ… **Fix #2: Phase 1 Startup Guide (docs/PHASE_1_STARTUP_GUIDE.md)** - Created comprehensive 252-day Job 893 startup documentation - Step-by-step Host startup procedure (DEVELOPMENT mode) - Monitoring instructions (5-minute auto-checks) - Timeline: 50-90 calendar days (automatic execution) βœ… **Fix #3: Status Correction (CLAUDE.md updated)** - Updated Gates Verification Summary with actual evidence - Corrected: Phase 1 is NOT RUNNING (awaiting manual startup) - Clarified: Production readiness = 0% (Phase 1 not yet executed) - Added: Realistic timeline to 100% readiness (~November 2026) ### CI/CD Pipeline Status **Continuous Integration (Testing) β€” βœ… ACTIVE** ```yaml # .gitea/workflows/ci.yml (auto-runs on push/PR) - Static Analysis: Python validation + unit tests - Backend: .NET build + DB migrations + 177 tests βœ… - Frontend: pnpm install + typecheck + 40 tests + build + E2E βœ… ``` **Expected:** ~15-30 minutes per push β†’ PASS/FAIL indication **Continuous Deployment (CD) β€” ❌ NOT CONFIGURED** - No automatic deployment to kartsell.taxbaik.com - Manual deployment only (after Phase 1 completes) ### Verified: Host Must Run in DEVELOPMENT Mode βœ… **Authentication Handler Routing:** - **Debug mode (-c Debug):** Uses `DevelopmentHeaderAuthenticationHandler` βœ… - Accepts `X-KArtSell-User` / `X-KArtSell-Role` headers - Suitable for testing and Gates 3-4 rehearsal - **Release mode (-c Release):** Uses `FailClosedAuthenticationHandler` ❌ - Denies all requests (403/404) - Not suitable for testing ```bash # Terminal 1: SSH Tunnel (keep open) ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7 # Terminal 2: Start Host in DEVELOPMENT/LOCAL/TEST MODE cd D:\JobRoomz\KArtSell.Aegis # Set actual API keys from Gitea Secrets (not test keys!) $env:KRX_OPENAPI = "" $env:OPENDART_API = "" $env:KIS_API_KEY = "" # CRITICAL: Run with --configuration Debug (DEVELOPMENT mode) # This enables DevelopmentHeaderAuthenticationHandler (reads X-KArtSell-User header) # appsettings.Development.json will be loaded automatically dotnet run --project src/KArtSell.Host --configuration Debug --no-build # Expected output: # info: Microsoft.Hosting.Lifetime[14] # Now listening on: http://127.0.0.1:5002 # info: Microsoft.Hosting.Lifetime[0] # Application started. Press Ctrl+C to shut down. # Expected output: # Now listening on: http://127.0.0.1:5002 # Application started. Press Ctrl+C to shut down. ``` **Why DEVELOPMENT mode?** - **Release mode (-c Release):** Uses `FailClosedAuthenticationHandler` β†’ all requests denied (403/404) - **Debug mode (default):** Uses `DevelopmentHeaderAuthenticationHandler` β†’ accepts `X-KArtSell-User` / `X-KArtSell-Role` headers **Gate 3 Request (Verified Working - 2026-08-03):** ```powershell $headers = @{ "X-KArtSell-User" = "gate3-rehearsal" "X-KArtSell-Role" = "Admin" "Content-Type" = "application/json" } $body = @{ modelId = "00000000-0000-0000-0000-000000000001" windowStart = "2024-01-02" windowEnd = "2024-09-10" phaseFilter = "All" } | ConvertTo-Json Invoke-WebRequest -Uri "http://127.0.0.1:5002/api/shadow-runs" ` -Method POST ` -Headers $headers ` -Body $body ` -ContentType "application/json" ``` --- ## Quick Start ### Prerequisites - .NET 10 SDK - Node.js 22 / pnpm 10 - SSH access to remote PostgreSQL server (178.104.200.7) ### Remote PostgreSQL Setup via SSH Port Forwarding The project database is hosted on `178.104.200.7`. Connect via SSH port forwarding: ```bash ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7 ``` This command: - Forwards local port 5432 to remote PostgreSQL (127.0.0.1:5432) - Keeps the tunnel open while you develop - Run in a separate terminal/window and keep it running during development **Windows (PowerShell):** ```powershell ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7 ``` **macOS/Linux:** ```bash ssh -L 5432:127.0.0.1:5432 kjh2064@178.104.200.7 ``` Once the tunnel is open, your local `localhost:5432` connects to the remote database. ### Local Development Environment ```bash # Backend: restore, build, migrate, test dotnet restore KArtSell.sln dotnet build KArtSell.sln -c Release dotnet run --project src/KArtSell.DbMigrator -c Release # Run backend tests dotnet test KArtSell.sln -c Release --logger trx # Run a single test dotnet test --filter "FullyQualifiedName=MyNamespace.MyTest.TestMethod" -c Release # Frontend: install, typecheck, test, build cd frontend pnpm install --frozen-lockfile pnpm typecheck pnpm test pnpm build # Run frontend E2E tests pnpm exec playwright install --with-deps chromium pnpm e2e # Run dev server (watch mode, hot reload) pnpm dev # Backend in another terminal ``` ### Database Connection ``` Host: localhost Port: 5432 Database: kartsell User: kartsell Password: kartsell ``` Environment variable: `KARTSELL_POSTGRES=Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell` **On Windows (PowerShell):** ```powershell $env:KARTSELL_POSTGRES="Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell" ``` **On macOS/Linux (bash):** ```bash export KARTSELL_POSTGRES="Host=localhost;Port=5432;Database=kartsell;Username=kartsell;Password=kartsell" ``` ## Architecture ### Backend: Modular Monolith + Vertical Slices #### Module Structure ``` src/ KArtSell.Host/ # Main ASP.NET Core app KArtSell.BuildingBlocks/ # Shared infrastructure (logging, serialization, extensions) KArtSell.DbMigrator/ # DbUp migrations KArtSell.Modules.ModelOperations/ # Model lifecycle, validation, activation KArtSell.Modules.SignalEngine/ # Trading signal generation ``` #### Vertical Slice Template Each feature is a complete, self-contained slice from HTTP endpoint to database, located under `Features//`: ``` Features// Endpoint.cs # FastEndpoints route handler (HTTP/contract/status codes) Request.cs # Input model with validation via Zod-like pattern Response.cs # Output model (DTO) Validator.cs # Fluent/Policy validation rules Handler.cs # Use case orchestration (Application layer) Policy.cs # Pure business decision logic (Domain layer) Sql.cs # Dapper queries (Data layer) Mapper.cs # Entity ↔ DTO mapping Jobs/ # Related Hangfire jobs Contracts/ # Event/Job contract definitions Tests/ # Unit/integration tests specific to this slice README.md # Traceability: requirements, ADRs, assumptions ``` **Key rule:** Endpoint handles HTTP concerns (routing, negotiation); Handler handles transaction boundaries; Policy makes decisions; Sql uses Dapper for explicit, schema-qualified queries. #### Design Principles - **No Generic Repository:** Each slice writes its own Dapper queries; promotes clarity. - **No Service Layer:** Handler + Policy + Sql replaces it; keeps flow visible. - **Module Isolation:** Modules do not query each other's source tables directly. - Synchronous: Use narrow Read Port services. - Asynchronous: Use Outbox/Inbox event patterns. - **PIT (Point-in-Time) Queries:** Must include `WHERE published_at <= cutoff` and revision resolver. - **Evidence & Audit:** Update/delete are blocked; new state appended as new revision. - **Migrations:** `src/KArtSell.DbMigrator` uses DbUp; file naming: `NNNN_description.sql`. Each module has ordered, checksummed migrations. ### Frontend: Vue 3 + Vite + Modular Feature Structure #### Directory Layout ``` frontend/src/ app/ # Core app initialization, routing, config features/ # Feature modules (one per business capability) / components/ # Scoped to this feature pages/ # Route-level pages stores/ # Pinia stores (state management) composables/ # Reusable logic (Vue 3 hooks) types/ # TS interfaces for this feature shared/ ui/ adapter/ # PrimeVue/AG Grid wrappers (mandatory boundary) components/ # Common components (QueryStateBoundary, PermissionGuard, CrudForm, etc.) layouts/ # Page layout templates crud/ # Generic CRUD form logic composables/ # Global composables (useFetch, useAuth, etc.) types/ # Global types, contracts stores/ # Global Pinia stores (auth, user, preferences) design-system/ # Design tokens, typography, color scales (PrimeVue theme overrides) ``` #### State Management Rules | State | Owner | Tool | |-------|-------|------| | API responses, cache, stale, retry | TanStack Query | @tanstack/vue-query | | Session, role, UI preferences | Global store | Pinia | | Form values, errors, touched | Form library | vee-validate + Zod | | URL filters, pagination, sorting | Router | vue-router query/params | | Large data tables, virtual scroll | Server-side row model | AG Grid server mode | **Anti-patterns:** - Do NOT duplicate API responses in Pinia. - Do NOT write 401/409/422/429/503 error handling in every screen. - Do NOT manage query cache manually; let TanStack Query handle it. #### Component Elevation Criteria Promote to `shared/ui/components/` only when: 1. **Same business meaning & permissions** (not just visual similarity). 2. **Repeated state/error handling logic** across 3+ consumers. 3. **Accessibility & testing** already fully implemented. **Always-shared components:** - `QueryStateBoundary` (loading/error/empty states) - `PermissionGuard` (RBAC enforcement) - `CrudForm` (standard CRUD form) - `VersionConflictDialog` (optimistic concurrency) - `DataFreshnessBadge` (cache/stale indicators) - `DataGridShell` (AG Grid wrapper with sorting, filtering, export) ### Database & Migrations #### DbUp - **Run at startup:** `KArtSell.DbMigrator` is the single source of truth. - **Schema ownership:** Each module owns its schema (e.g., `model_operations.*`, `signal_engine.*`). - **Safety:** Migrations are idempotent and checksummed; failed migration rolls back and waits for manual intervention. - **Test:** Each migration has fresh/upgrade/re-run/failure-recovery tests in CI. #### Query Patterns ```csharp // DO: Schema-qualified, explicit columns, cancellation token const string sql = """ SELECT id, name, created_at FROM model_operations.signals WHERE published_at <= @cutoff AND status = @status ORDER BY created_at DESC """; // DON'T: SELECT *, generic repository, no token const string sql = "SELECT * FROM signals WHERE status = @status"; ``` #### Async Coupling: Outbox/Inbox - **Outbox:** When a command succeeds, events are inserted into `outbox` in the same transaction. - **Inbox:** A Hangfire job polls the outbox, publishes events, and marks them as processed. - **Idempotency:** Each inbox handler is idempotent; replayed events are no-ops. ### Hangfire (Background Jobs & Scheduling) #### Job Design - **Not a business decision maker:** Hangfire executes approved Application Commands, not policies. - **Idempotency key:** Each job must be replayable without side effects. - **Watermark & version set:** Track input/output state across retries. - **Queue isolation:** `q-customer-sla` (business SLA) is separate from `q-research` (non-critical). - **Retry classification:** - `transient` (network glitch, retry immediately) - `permanent` (bad input, log & alert) - `dq` (data quality issue, quarantine for manual review) - `business-hold` (awaiting approval or external event) #### Example Job Structure ```csharp public class MyJobCommand : ICommand { public string IdempotencyKey { get; set; } public Guid JobRunId { get; set; } public Guid CorrelationId { get; set; } } ``` Jobs do not call other jobs directly; instead, they emit events or check readiness gates. ### SignalR (Real-Time Push) Used for live notifications (model activation events, approval notifications). Follows Hub/Group pattern with correlation to `CorrelationId` for traceability. ## Testing Strategy ### xUnit Backend Tests #### Test Organization ``` tests/ KArtSell.ArchitectureTests/ # Compile-time architecture rules KArtSell.ModelOperations.UnitTests/ KArtSell.SignalEngine.UnitTests/ KArtSell.Integration.Tests/ # E2E with real DB (if exists) ``` #### Test Levels 1. **Unit:** Pure functions (Policy, Mapper), no I/O. Fast, deterministic. 2. **Integration:** Handler + Dapper + real PostgreSQL. Validates transaction boundaries, Outbox/Inbox. 3. **Data:** SQL query validation, schema conformance, index effectiveness. 4. **E2E:** Full HTTP stack; used sparingly for critical paths. 5. **Golden/Frozen OOS:** Before merging algorithm changes, lock baseline and diff against new run. #### Run Tests ```bash dotnet test KArtSell.sln -c Release dotnet test --filter "Category=Integration" -c Release dotnet test --filter "FullyQualifiedName~UnitTests" -c Release --verbosity quiet ``` ### Vitest Frontend Tests ```bash cd frontend pnpm test # Run all tests pnpm test -- --reporter=verbose # Verbose output pnpm test -- # Run subset pnpm test -- --coverage # Coverage report ``` ### Playwright E2E ```bash cd frontend pnpm e2e # Run all E2E tests headless pnpm e2e -- --debug # Debug mode (browser stays open) pnpm exec playwright test --headed # Run with browser UI ``` ## Observability ### Logging - **Tool:** Serilog with structured properties. - **Correlation:** All logs are tagged with `CorrelationId`, `JobRunId`, `EvidenceId`. - **Sensitive data:** PII, tokens, API keys are NEVER logged (use redaction middleware). - **Levels:** INFO (user actions), DEBUG (internal flow), WARN (recoverable issues), ERROR (unrecoverable, alert required). ### Tracing & Metrics - **Tool:** OpenTelemetry for distributed tracing and metrics. - **Spans:** HTTP requests, database queries, job execution, event processing. - **Alerts:** Send to Telegram integration (configured in `KArtSell.Host` startup). ### Operational Dashboards (Priority Order) 1. **Batch SLA:** Job completion times, queue depths (q-customer-sla vs q-research). 2. **Data Quality Quarantine:** Jobs marked `dq` by retry classifier. 3. **Duplicate Detection:** Outbox duplicate events. 4. **Reconciliation Breaks:** Mismatch between expected and actual state (Evidence vs current). 5. **Model Drift:** OOS (out-of-sample) performance metrics. ## Common Workflows ### Adding a New Vertical Slice 1. **Scaffold the structure:** ```bash python tools/scaffold_vertical_slice.py --name MyFeature --module ModelOperations ``` 2. **Define the contract** (before code): - Request/Response DTOs in `Contracts/` - Event schema in `Contracts/Events/` if async coupling needed - Validation rules (vee-validate schema on FE, Fluent on BE) 3. **Implement backend slice:** - `Handler.cs`: Orchestration, transaction handling - `Policy.cs`: Pure business logic - `Sql.cs`: Dapper queries (schema-qualified, no SELECT *) - `Endpoint.cs`: HTTP routing & status codes - `README.md`: Traceability link to requirement/ADR 4. **Write tests:** - Unit: Policy, Mapper logic - Integration: Handler + Dapper + real DB - Verify Outbox events are created if async 5. **Implement frontend feature:** - Feature module under `features//` - Use `features//pages/` for route-level components - Use `shared/ui/adapter/` for any UI component usage - Form validation with vee-validate + Zod schema from BE contract 6. **Validation gates (pre-merge):** - Architecture tests pass - DB migration is idempotent (fresh/upgrade test) - No SELECT *, no direct cross-module queries - Outbox/Inbox tests if async - Frontend typecheck + test + build - E2E smoke test (if user-facing) ### Refactoring (Characterized, Isolated, Verified) 1. **Characterize:** Lock current behavior with tests + perf baseline + Golden data. 2. **Isolate:** Separate I/O (Dapper queries, HTTP) from logic (Policy). 3. **Transform:** One small change at a time (rename, extract, move). 4. **Verify:** All tests pass, no perf regression, backtest algorithm changes against Golden. 5. **Simplify:** Delete dead abstractions, feature flags, branches. 6. **Observe:** Post-release SLO/DQ/model drift monitoring. 7. **Close Debt:** Update Debt ID, leave ADR for future maintainers. ### Creating a Background Job 1. **Define the command:** ```csharp public class MyJobCommand : ICommand { public Guid IdempotencyKey { get; set; } public Guid CorrelationId { get; set; } public string InputData { get; set; } } ``` 2. **Implement the handler:** - Idempotent: Re-run should be safe and produce same result. - Classify failures: transient/permanent/dq/business-hold. - Emit events to Outbox for async notifications. 3. **Schedule via Hangfire:** ```csharp await backgroundJobClient.EnqueueAsync(h => h.Handle(command)); ``` 4. **Test retry & replay scenarios:** - Job runs successfully. - Job fails and is retried (verify idempotency). - Job is replayed from cold state (verify determinism). ## Guardrails & Anti-Patterns ### βœ… Work Decision Checklist (from AGENTS.md v16.0) Before writing code, verify: - [ ] **SOLID:** Single responsibility? Dependency inversion? Substitutable abstractions? - [ ] **Complexity:** Cyclomatic complexity ≀ 10 per method? (Policy exceptions allowed) - [ ] **Audit:** Evidence/Revision tracked? PIT query present? `published_at <= cutoff`? - [ ] **Necessity:** Grounded in requirement/ADR/issue? Not "might need later"? - [ ] **Normalization:** Writes are 3NF + append + revision? Reads use denormalized projections? - [ ] **Simplicity:** Topβ†’bottom readability? No hidden assumptions? No magic values? - [ ] **Pattern:** Follows Vertical Slice / Job / Component standard? Approved contract? - [ ] **Guardrails:** Source/Assumption/Decision documented? AI decisions traced? - [ ] **Traceability:** Artifact preserved? Reproducible? Linked to ADR/Issue/Debt ID? - [ ] **Safety:** Idempotent? Rollback-safe? Failure modes handled? No partial success? - [ ] **Maturity:** Contract/schema/test BEFORE implementation? No placeholders merged? - [ ] **Right Way:** No shortcuts (--no-verify, force push)? Root cause fixed? Code reviewed? - [ ] **Debt:** Tech debt registered with ID? Paydown target met? No new unbounded debt? ### AI Input Packet (from VIBE_CODING_GUARDRAILS.md) **Before requesting code from Claude, provide all 8:** 1. **Source:** Policy ID, ADR, requirement, data contract, reference implementation 2. **Slice Spec:** User goal, non-goal, state transitions, RBAC constraints 3. **Screen Spec:** Component tree, state ownership, a11y requirements 4. **Contract:** Endpoint path/verb, event schema, status codes, idempotency, ETag handling 5. **Data:** Schema (3NF write model), columns, PIT conditions, migration strategy, index plan 6. **Tests:** Unit/integration/data/E2E/Golden scenarios, failure cases, replay scenarios 7. **Ops:** Metrics, alerts, runbook, rollback procedure, owner/secondary 8. **Output Rule:** Changed files, verification commands, assumptions, residual risks ### Blocking Rules (Non-Negotiable) - ❌ **No gold-plating:** Every line must serve a requirement. "Might need later" is debt, not code. - ❌ **No undocumented magic:** Policy IDs, thresholds, DB columns must trace to approved source. - ❌ **No mixed concerns:** One PR = one Vertical Slice or one refactoring goal. Never both. - ❌ **No skipped tests:** Failing/skipped tests must be fixed or logged as DECISION_REQUIRED. - ❌ **No SELECT \*:** Always explicit columns. Dapper + schema-qualified SQL only. - ❌ **No direct cross-module queries:** Use approved contracts and read models only. - ❌ **No DateTime.Now:** Inject IClock. No random/network/system time in Policy. - ❌ **No partial success:** DB state must be consistent after success/failure. No "kind of failed". - ❌ **No policy in Job:** Jobs execute Commands, not make decisions. Decisions stay in Domain. - ❌ **No real customer data in code:** Never in prompt, fixture, log, trace, or test. ### Model Operations Specifics - **Model lifecycle:** Freeze β†’ Mature β†’ Score β†’ Diagnose β†’ Hypothesis β†’ Challenger β†’ Validate β†’ Review β†’ Manual Activation (no auto-learning, auto-promotion, auto-ordering). - **Sell priority (immutable):** `HARD_IMPAIRMENT β†’ PORTFOLIO_SURVIVAL β†’ DYNAMIC_PROFIT_FLOOR β†’ CONCENTRATION/LIQUIDITY β†’ OPPORTUNITY_COST β†’ REENTRY_OPTION`. - **Non-value-loss sell:** Requires ReentryWatch, new CycleId/Lot, step intervals, expiry, dedup. - **Activation gating:** Requires ModelCard, OOS/PBO/DSR evidence, maker-checker approval, effective_at, rollback justification. ## Gitea API Automation & Actions Secrets ### Gitea Actions Secrets **External API keys are stored in Gitea Actions Secrets (not in .env or code).** **Location:** `https://gitea.taxbaik.com/kjh2064/KArtSell.Aegis/settings/actions/secrets` **Available secrets:** - `KRX_OPENAPI` β€” Korea Exchange OpenAPI (stock prices, indices, market data) - `OPENDART_API` β€” OpenDart financial disclosure & quarterly reporting - `KIS_APP_KEY` / `KIS_APP_SECRET` β€” Korea Investment & Securities trading API **Usage in CI/CD (`.gitea/workflows/*.yml`):** ```yaml env: KRX_OPENAPI: ${{ secrets.KRX_OPENAPI }} OPENDART_API: ${{ secrets.OPENDART_API }} KIS_APP_KEY: ${{ secrets.KIS_APP_KEY }} KIS_APP_SECRET: ${{ secrets.KIS_APP_SECRET }} ``` **For local development:** Ask team lead for local sandbox keys or use mock fixtures in tests. ### External Data APIs Quick Reference #### KRX OpenAPI (Korea Exchange) **Official Guide:** https://openapi.krx.co.kr/contents/OPP/INFO/service/OPPINFO004.cmd **Available Services:** | Service | Link | Endpoint | Method | Auth | |---------|------|----------|--------|------| | **μ§€μˆ˜ (Indices)** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES001_S1.cmd | `/svc/apis/idx/krx_dd_trd` | POST | AUTH_KEY header | | **주식 (Stocks)** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES002_S1.cmd | `/svc/apis/sco/...` | POST | AUTH_KEY header | | **μ¦κΆŒμƒν’ˆ** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES003_S1.cmd | `/svc/apis/sec/...` | POST | AUTH_KEY header | | **μ±„κΆŒ** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES004_S1.cmd | `/svc/apis/bon/...` | POST | AUTH_KEY header | | **νŒŒμƒμƒν’ˆ** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES005_S1.cmd | `/svc/apis/drv/...` | POST | AUTH_KEY header | | **μΌλ°˜μƒν’ˆ** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES006_S1.cmd | `/svc/apis/gen/...` | POST | AUTH_KEY header | | **ESG** | https://openapi.krx.co.kr/contents/OPP/USES/service/OPPUSES007_S1.cmd | `/svc/apis/esg/...` | POST | AUTH_KEY header | **Current Implementation:** - βœ… Indices API: `/svc/apis/idx/krx_dd_trd` (POST + JSON body `{"basDd":"YYYYMMDD"}`) - πŸ“ Location: `src/KArtSell.Modules.ModelOperations/ShadowRun/Services/KrxDataService.cs` - πŸ“ Automatic Fallback: API failure β†’ stub data (realistic values for testing) #### OpenDart API (Financial Disclosure) **Official Guide:** https://opendart.fss.or.kr/guide/main.do **Available API Groups:** | Group | Link | Endpoint | Method | Auth | Purpose | |-------|------|----------|--------|------|---------| | **κ³΅μ‹œμ •λ³΄** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS001 | `/api/list.json` | GET | crtfc_key | Disclosure search | | **μ •κΈ°λ³΄κ³ μ„œ μ£Όμš”μ •λ³΄** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS002 | `/api/...` | GET | crtfc_key | Annual report highlights | | **μ •κΈ°λ³΄κ³ μ„œ μž¬λ¬΄μ •λ³΄** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS003 | `/api/...` | GET | crtfc_key | Quarterly financial data | | **μ§€λΆ„κ³΅μ‹œ 쒅합정보** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS004 | `/api/...` | GET | crtfc_key | Equity disclosure | | **μ£Όμš”μ‚¬ν•­λ³΄κ³ μ„œ** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS005 | `/api/...` | GET | crtfc_key | Material event reports | | **μ¦κΆŒμ‹ κ³ μ„œ** | https://opendart.fss.or.kr/guide/detail.do?apiGrpCd=DS006 | `/api/...` | GET | crtfc_key | Security registration | **Current Implementation:** - βœ… Disclosure Info: `/api/list.json?crtfc_key=KEY&corp_code=CODE` (GET) - πŸ“ Location: `src/KArtSell.Host/Observability/OpenDartService.cs` - πŸ“ Note: Current endpoint returns disclosure listings, not quarterly financial data - πŸ“ For financial data: Use DS003 group (μ •κΈ°λ³΄κ³ μ„œ μž¬λ¬΄μ •λ³΄) ### Gitea API Automation (Optional but Recommended) ### Environment Setup ```bash # Enable Gitea API automation (optional) $env:GITEA_TOKEN_TAXBAIK = "your-gitea-api-token" # Windows PowerShell export GITEA_TOKEN_TAXBAIK="your-gitea-api-token" # macOS/Linux ``` ### Common Tasks **1. Verify PR Build Status** ```bash # After successful build/test, comment on PR: curl -X POST \ -H "Authorization: token $GITEA_TOKEN_TAXBAIK" \ -H "Content-Type: application/json" \ -d '{"body":"βœ… Build: PASS\nβœ… Tests: 41/41 PASS\nβœ… Security: Clean"}' \ https://gitea.taxbaik.com/api/v1/repos/kjh2064/KArtSell.Aegis/issues/{PR_NUMBER}/comments ``` **2. Auto-Label PRs by Module** ```bash # Label PR with affected modules curl -X POST \ -H "Authorization: token $GITEA_TOKEN_TAXBAIK" \ -d '["architecture","performance","observability"]' \ https://gitea.taxbaik.com/api/v1/repos/kjh2064/KArtSell.Aegis/issues/{PR_NUMBER}/labels ``` **3. Link to Tech Debt Registry** ```bash # Reference debt in commit message (e.g., in CI job): git commit -m "fix: CA1822 static method hints - TECH-001 Resolves technical debt from NoWarn bypass. Part of quarterly paydown target (20% per quarter). Co-Authored-By: Claude Haiku 4.5 " ``` **4. Gitea Actions Integration** (`.gitea/workflows/ci.yml`) ```yaml - name: Post PR verification results if: always() run: | BODY="## Verification Results - Build: ${{ job.status }} - Tests: 41/41 βœ… - Debt Paydown: TECH-001 resolved [See full logs](https://gitea.taxbaik.com/kjh2064/KArtSell.Aegis/actions)" curl -X POST \ -H "Authorization: token ${{ secrets.GITEA_TOKEN }}" \ -H "Content-Type: application/json" \ -d "{\"body\":\"$BODY\"}" \ https://gitea.taxbaik.com/api/v1/repos/kjh2064/KArtSell.Aegis/issues/${{ github.event.pull_request.number }}/comments ``` --- ## Tools & Scripts ### Scaffolding ```bash python tools/scaffold_vertical_slice.py --name MyFeature --module ModelOperations python tools/scaffold_ui_screen.py --name MyScreen --feature MyFeature ``` ### Validation ```bash python tools/validate_v16.py # Full v16 validation (contracts, migrations, Python tests) python -m unittest discover # Run all Python unit tests ``` ### FastEndpoints - Docs: [FastEndpoints GitHub](https://github.com/FastEndpoints/FastEndpoints) - Pattern: Each endpoint maps to a Vertical Slice; routes are discovered automatically. ## Documentation & Resources ### Key Documents - `docs/03_ARCHITECTURE_BE_FE.md` β€” Modular Monolith, Vertical Slice, Dapper, Hangfire, FE state ownership rules. - `docs/06_VIBE_CODING_GUARDRAILS.md` β€” AI input packets, blocking rules, refactoring methodology. - `contracts/ui/ui-adapter.v3.json` β€” FE adapter contract (PrimeVue/AG Grid wrapper boundaries). - `contracts/schedules/model-operations.v3.json` β€” Job scheduling contract. - `README.md` β€” Project status, v16 delta, validation gates. ### Contracts Directory ``` contracts/ ui/ # Frontend adapter & component contracts schedules/ # Job scheduling contracts data/ # Domain data models (PIT envelope, projection) events/ # Async event schemas metrics/ # Outcome metrics schema ``` ## Tech Debt Management (from AGENTS.md v16.0) Every suppressed rule, deferred refactor, and architectural compromise is debt. **Manage proactively:** ### Tech Debt Registry Location: [`TECH_DEBT_REGISTER.md`](TECH_DEBT_REGISTER.md) Format: ``` | ID | Category | Impact | Effort | Status | Debt | Owner | Notes | |----|----------|--------|--------|--------|------|-------|-------| | DEBT-001 | Code Analysis (CA1822) | Medium | Low | Backlog | Static method hints | Team | Can batch with refactor | | DEBT-002 | Code Analysis (CA1873) | Low | Low | Backlog | Array allocation in logs | Team | Remove when performance-critical | ``` **Impact/Effort Matrix:** - **High Impact / Low Effort:** Sprint ASAP (quick wins) - **High Impact / High Effort:** Roadmap (quarterly sprint) - **Low Impact / Low Effort:** Batch with feature work - **Low Impact / High Effort:** Monitor; defer unless blocking ### Current Debt (Provisional) From `Directory.Build.props` NoWarn: - `CA1822` (static method hints) β€” Low priority, batch during refactors - `CA1873` (array allocation in logging) β€” Monitor, low impact - `CA1305` (culture-specific formatting) β€” Accept as-is for Serilog - `CA1707` (test naming convention) β€” xUnit uses underscores; accept - `CA1861` (static readonly arrays) β€” Low priority, batch - `xUnit2031` (Assert.Single filter) β€” Test analyzer; can defer ### Paydown Target **Quarterly paydown goal:** 20% of debt list resolved (by impact, not count). Track in: - Sprint retrospectives - PR descriptions (reference Debt ID when resolving) - README.md status section --- ## Validation Gates (Not Yet Passed) Do NOT claim production readiness until: - βœ… `.NET 10 restore/build/test` on CI passes consistently - ⏳ `pnpm frozen install/typecheck/Vitest/build/Playwright` on CI passes (pending PR 4) - ⏳ PostgreSQL DbUp fresh/upgrade/re-run/failure-recovery tests pass (pending PR 5) - ⏳ Outbox/Inbox crash-recovery & audit reconciliation rehearsal passes - ❌ 252+ trading-day shadow run with OOS at multiple market phases - ❌ PBO (probability of backtest overfit) and DSR (daily sharpe ratio) evidence Before all gates pass: **No production deployment, no advisory-with-automation, no auto-ordering, no auto-model-promotion.**