chore: bootstrap trellis workspace and sync deployment settings
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
# Code Reuse Thinking Guide
|
||||
|
||||
> **Purpose**: Stop and think before creating new code - does it already exist?
|
||||
|
||||
---
|
||||
|
||||
## The Problem
|
||||
|
||||
**Duplicated code is the #1 source of inconsistency bugs.**
|
||||
|
||||
When you copy-paste or rewrite existing logic:
|
||||
- Bug fixes don't propagate
|
||||
- Behavior diverges over time
|
||||
- Codebase becomes harder to understand
|
||||
|
||||
---
|
||||
|
||||
## Before Writing New Code
|
||||
|
||||
### Step 1: Search First
|
||||
|
||||
```bash
|
||||
# Search for similar function names
|
||||
grep -r "functionName" .
|
||||
|
||||
# Search for similar logic
|
||||
grep -r "keyword" .
|
||||
```
|
||||
|
||||
### Step 2: Ask These Questions
|
||||
|
||||
| Question | If Yes... |
|
||||
|----------|-----------|
|
||||
| Does a similar function exist? | Use or extend it |
|
||||
| Is this pattern used elsewhere? | Follow the existing pattern |
|
||||
| Could this be a shared utility? | Create it in the right place |
|
||||
| Am I copying code from another file? | **STOP** - extract to shared |
|
||||
|
||||
---
|
||||
|
||||
## Common Duplication Patterns
|
||||
|
||||
### Pattern 1: Copy-Paste Functions
|
||||
|
||||
**Bad**: Copying a validation function to another file
|
||||
|
||||
**Good**: Extract to shared utilities, import where needed
|
||||
|
||||
### Pattern 2: Similar Components
|
||||
|
||||
**Bad**: Creating a new component that's 80% similar to existing
|
||||
|
||||
**Good**: Extend existing component with props/variants
|
||||
|
||||
### Pattern 3: Repeated Constants
|
||||
|
||||
**Bad**: Defining the same constant in multiple files
|
||||
|
||||
**Good**: Single source of truth, import everywhere
|
||||
|
||||
---
|
||||
|
||||
## When to Abstract
|
||||
|
||||
**Abstract when**:
|
||||
- Same code appears 3+ times
|
||||
- Logic is complex enough to have bugs
|
||||
- Multiple people might need this
|
||||
|
||||
**Don't abstract when**:
|
||||
- Only used once
|
||||
- Trivial one-liner
|
||||
- Abstraction would be more complex than duplication
|
||||
|
||||
---
|
||||
|
||||
## After Batch Modifications
|
||||
|
||||
When you've made similar changes to multiple files:
|
||||
|
||||
1. **Review**: Did you catch all instances?
|
||||
2. **Search**: Run grep to find any missed
|
||||
3. **Consider**: Should this be abstracted?
|
||||
|
||||
---
|
||||
|
||||
## Gotcha: Asymmetric Mechanisms Producing Same Output
|
||||
|
||||
**Problem**: When two different mechanisms must produce the same file set (e.g., recursive directory copy for init vs. manual `files.set()` for update), structural changes (renaming, moving, adding subdirectories) only propagate through the automatic mechanism. The manual one silently drifts.
|
||||
|
||||
**Symptom**: Init works perfectly, but update creates files at wrong paths or misses files entirely.
|
||||
|
||||
**Prevention checklist**:
|
||||
- [ ] When migrating directory structures, search for ALL code paths that reference the old structure
|
||||
- [ ] If one path is auto-derived (glob/copy) and another is manually listed, the manual one needs updating
|
||||
- [ ] Add a regression test that compares outputs from both mechanisms
|
||||
|
||||
---
|
||||
|
||||
## Checklist Before Commit
|
||||
|
||||
- [ ] Searched for existing similar code
|
||||
- [ ] No copy-pasted logic that should be shared
|
||||
- [ ] Constants defined in one place
|
||||
- [ ] Similar patterns follow same structure
|
||||
@@ -0,0 +1,116 @@
|
||||
# Cross-Layer Thinking Guide
|
||||
|
||||
> Purpose: prevent contract drift across `docs/protocols` -> backend -> frontend.
|
||||
|
||||
---
|
||||
|
||||
## Practical Conventions
|
||||
|
||||
1. Treat `docs/protocols/**` as the contract source of truth before code changes.
|
||||
2. For any API/event/error contract change, verify all three sides in one pass:
|
||||
- Protocol doc
|
||||
- Backend transport/output
|
||||
- Frontend parsing/mapping
|
||||
3. Prefer explicit boundary checks over implicit assumptions (status/code/date/run lifecycle).
|
||||
4. When touching cross-layer behavior, keep a short written checkpoint list in task notes (aligned with `.opencode/commands/trellis/finish-work.md` cross-layer verification items).
|
||||
|
||||
---
|
||||
|
||||
## Project-Specific Boundary Map
|
||||
|
||||
| Boundary | Contract Source | Backend Evidence | Frontend Evidence |
|
||||
|---|---|---|---|
|
||||
| HTTP errors | `docs/protocols/common/http-error-codes.md` | `backend/src/core/http/response.py`, `backend/src/app.py` | `apps/lib/data/network/api_exception.dart`, `apps/lib/data/network/error_code_mapper.dart` |
|
||||
| Todo model | `docs/protocols/models/todo.md` | `backend/src/v1/todo/schemas.py`, `backend/src/v1/todo/router.py` | `apps/lib/features/todo/data/apis/todo_api.dart` |
|
||||
| Agent SSE events | `docs/protocols/agent/sse-events.md` | `backend/src/v1/agent/router.py` | `apps/lib/features/chat/data/apis/chat_api_impl.dart`, `apps/lib/core/chat/ag_ui_service.dart` |
|
||||
|
||||
## Real File Path Examples
|
||||
|
||||
- `docs/protocols/common/http-error-codes.md`
|
||||
- `backend/src/v1/agent/router.py`
|
||||
- `apps/lib/core/chat/ag_ui_service.dart`
|
||||
|
||||
---
|
||||
|
||||
## Contract Checkpoints (Required for cross-layer work)
|
||||
|
||||
### 1) Endpoint and payload shape
|
||||
|
||||
- Confirm method/path/query/body on both sides.
|
||||
- Example pair:
|
||||
- Backend: `backend/src/v1/todo/router.py` (`/api/v1/todos`, query `status/priority`)
|
||||
- Frontend: `apps/lib/features/todo/data/apis/todo_api.dart` (`getTodos`, `createTodo`, `reorderTodos`)
|
||||
|
||||
### 2) Error code transport and mapping
|
||||
|
||||
- Backend should return RFC7807 + stable `code`/`params`.
|
||||
- Frontend should localize by `code`, not by free-text `detail`.
|
||||
- Example triplet:
|
||||
- `docs/protocols/common/http-error-codes.md`
|
||||
- `backend/src/core/http/response.py`
|
||||
- `apps/lib/data/network/error_code_mapper.dart`
|
||||
|
||||
### 3) Event lifecycle completeness (SSE)
|
||||
|
||||
- Ensure lifecycle expectations are symmetric:
|
||||
- backend stream semantics (filter + terminal event)
|
||||
- frontend stream completion/recovery logic
|
||||
- Example pair:
|
||||
- `backend/src/v1/agent/router.py` (target run filtering, terminal events)
|
||||
- `apps/lib/core/chat/ag_ui_service.dart` (terminal event required for stream completion)
|
||||
|
||||
### 4) Date/time and ID boundary parsing
|
||||
|
||||
- Check datetime serialization/parsing and UUID/string assumptions across layers.
|
||||
- Example:
|
||||
- `backend/src/v1/todo/schemas.py` (`datetime`, `UUID`)
|
||||
- `apps/lib/features/todo/data/apis/todo_api.dart` (`DateTime.parse`, string IDs)
|
||||
|
||||
---
|
||||
|
||||
## Project Examples
|
||||
|
||||
### Example A: Todo contract alignment
|
||||
|
||||
1. Protocol defines field names and ordering rules: `docs/protocols/models/todo.md`
|
||||
2. Backend enforces schema and route behavior: `backend/src/v1/todo/schemas.py`, `backend/src/v1/todo/router.py`
|
||||
3. Frontend maps to model parsing and request payloads: `apps/lib/features/todo/data/apis/todo_api.dart`
|
||||
|
||||
Checklist:
|
||||
|
||||
- [ ] field names (`schedule_item_ids`, `created_at`, `updated_at`) match
|
||||
- [ ] enums/ranges (`status`, `priority`) match
|
||||
- [ ] reorder payload shape (`items: [{id, priority, order}]`) matches
|
||||
|
||||
### Example B: Agent SSE run lifecycle alignment
|
||||
|
||||
1. Protocol lifecycle doc: `docs/protocols/agent/sse-events.md`
|
||||
2. Backend stream filtering/termination: `backend/src/v1/agent/router.py`
|
||||
3. Frontend consumption/recovery: `apps/lib/core/chat/ag_ui_service.dart`
|
||||
|
||||
Checklist:
|
||||
|
||||
- [ ] frontend sends `runId` query for `/events`
|
||||
- [ ] backend only emits target run to subscriber
|
||||
- [ ] frontend treats `RUN_FINISHED`/`RUN_ERROR` as terminal for stream completion
|
||||
|
||||
---
|
||||
|
||||
## Anti-patterns (with current evidence)
|
||||
|
||||
- Changing backend error codes without updating protocol registry and frontend mapper.
|
||||
- Synchronization points: `http-error-codes.md` + `error_code_mapper.dart`.
|
||||
- Inferring user-facing behavior from `detail` free text.
|
||||
- Frontend already supports code-first mapping in `api_exception.dart`; bypassing this creates localization drift.
|
||||
- Swallowing boundary failures in stream/auth paths.
|
||||
- Existing weak branches (do not extend):
|
||||
- `apps/lib/app/di/injection.dart` refresh callback catch returns `false`
|
||||
- `apps/lib/core/chat/ag_ui_service.dart` malformed SSE payload parse catch ignores payload
|
||||
- `backend/src/v1/agent/router.py` SSE slot acquire/release failure falls back to warning + continue
|
||||
|
||||
---
|
||||
|
||||
## Uncertainties / Gaps
|
||||
|
||||
- No repository-wide automated checker currently validates full cross-layer parity (protocol doc <-> backend implementation <-> frontend mapping/event consumer).
|
||||
- Some fallback branches exist for runtime resilience in legacy paths; whether to hard-fail vs degrade is not yet uniformly specified across all modules.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Thinking Guides
|
||||
|
||||
> **Purpose**: Expand your thinking to catch things you might not have considered.
|
||||
|
||||
---
|
||||
|
||||
## Why Thinking Guides?
|
||||
|
||||
**Most bugs and tech debt come from "didn't think of that"**, not from lack of skill:
|
||||
|
||||
- Didn't think about what happens at layer boundaries → cross-layer bugs
|
||||
- Didn't think about code patterns repeating → duplicated code everywhere
|
||||
- Didn't think about edge cases → runtime errors
|
||||
- Didn't think about future maintainers → unreadable code
|
||||
|
||||
These guides help you **ask the right questions before coding**.
|
||||
|
||||
---
|
||||
|
||||
## Available Guides
|
||||
|
||||
| Guide | Purpose | When to Use |
|
||||
|-------|---------|-------------|
|
||||
| [Code Reuse Thinking Guide](./code-reuse-thinking-guide.md) | Identify patterns and reduce duplication | When you notice repeated patterns |
|
||||
| [Cross-Layer Thinking Guide](./cross-layer-thinking-guide.md) | Think through data flow across layers | Features spanning multiple layers |
|
||||
|
||||
---
|
||||
|
||||
## Quick Reference: Thinking Triggers
|
||||
|
||||
### When to Think About Cross-Layer Issues
|
||||
|
||||
- [ ] Feature touches 3+ layers (API, Service, Component, Database)
|
||||
- [ ] Data format changes between layers
|
||||
- [ ] Multiple consumers need the same data
|
||||
- [ ] You're not sure where to put some logic
|
||||
|
||||
→ Read [Cross-Layer Thinking Guide](./cross-layer-thinking-guide.md)
|
||||
|
||||
### When to Think About Code Reuse
|
||||
|
||||
- [ ] You're writing similar code to something that exists
|
||||
- [ ] You see the same pattern repeated 3+ times
|
||||
- [ ] You're adding a new field to multiple places
|
||||
- [ ] **You're modifying any constant or config**
|
||||
- [ ] **You're creating a new utility/helper function** ← Search first!
|
||||
|
||||
→ Read [Code Reuse Thinking Guide](./code-reuse-thinking-guide.md)
|
||||
|
||||
---
|
||||
|
||||
## Pre-Modification Rule (CRITICAL)
|
||||
|
||||
> **Before changing ANY value, ALWAYS search first!**
|
||||
|
||||
```bash
|
||||
# Search for the value you're about to change
|
||||
grep -r "value_to_change" .
|
||||
```
|
||||
|
||||
This single habit prevents most "forgot to update X" bugs.
|
||||
|
||||
---
|
||||
|
||||
## How to Use This Directory
|
||||
|
||||
1. **Before coding**: Skim the relevant thinking guide
|
||||
2. **During coding**: If something feels repetitive or complex, check the guides
|
||||
3. **After bugs**: Add new insights to the relevant guide (learn from mistakes)
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Found a new "didn't think of that" moment? Add it to the relevant guide.
|
||||
|
||||
---
|
||||
|
||||
**Core Principle**: 30 minutes of thinking saves 3 hours of debugging.
|
||||
Reference in New Issue
Block a user