Bundle mission-control into Triple-C instead of cloning from GitHub
All checks were successful
Build App / compute-version (push) Successful in 2s
Build App / build-macos (push) Successful in 2m47s
Build Container / build-container (push) Successful in 9m0s
Build App / build-linux (push) Successful in 4m41s
Build App / build-windows (push) Successful in 5m33s
Build App / create-tag (push) Successful in 3s
Build App / sync-to-github (push) Successful in 10s
All checks were successful
Build App / compute-version (push) Successful in 2s
Build App / build-macos (push) Successful in 2m47s
Build Container / build-container (push) Successful in 9m0s
Build App / build-linux (push) Successful in 4m41s
Build App / build-windows (push) Successful in 5m33s
Build App / create-tag (push) Successful in 3s
Build App / sync-to-github (push) Successful in 10s
The mission-control (Flight Control) project is being closed upstream. This embeds the project files directly in the repo under container/mission-control/, bakes them into the Docker image at /opt/mission-control, and copies them into place at container startup instead of git cloning from GitHub. Also adds missing osc52-clipboard, audio-shim, and triple-c-sso-refresh to the programmatic Docker build context in image.rs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
383
container/mission-control/docs/legs.md
Normal file
383
container/mission-control/docs/legs.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# Legs
|
||||
|
||||
Legs are the AI-optimized layer of Flight Control. They provide structured, explicit instructions that AI agents can execute without ambiguity.
|
||||
|
||||
## What is a Leg?
|
||||
|
||||
A leg is a single, atomic unit of implementation work. Legs are:
|
||||
|
||||
- **Explicit**: No ambiguity about what "done" means
|
||||
- **Bounded**: Clear start and end points
|
||||
- **Context-complete**: All necessary information included
|
||||
- **AI-consumable**: Structured for machine parsing
|
||||
|
||||
### Leg vs. Flight vs. Mission
|
||||
|
||||
| Aspect | Mission | Flight | Leg |
|
||||
|--------|---------|--------|-----|
|
||||
| Scope | Outcome | Feature | Task |
|
||||
| Duration | Days-weeks | Hours-days | Minutes-hours |
|
||||
| Modifications | Allowed | Allowed | Create new instead |
|
||||
| Audience | Humans | Developers/AI | AI agents |
|
||||
|
||||
## Leg Structure
|
||||
|
||||
Legs follow a consistent structure optimized for AI consumption:
|
||||
|
||||
```markdown
|
||||
# Leg: {slug}
|
||||
|
||||
## Flight Link
|
||||
[Parent flight](../flight.md)
|
||||
|
||||
## Objective
|
||||
Single sentence describing what this leg accomplishes.
|
||||
|
||||
## Context
|
||||
Information the AI needs to understand this task.
|
||||
|
||||
## Inputs
|
||||
- What exists before this leg runs
|
||||
|
||||
## Outputs
|
||||
- What exists after this leg completes
|
||||
|
||||
## Acceptance Criteria
|
||||
- [ ] Criterion 1
|
||||
- [ ] Criterion 2
|
||||
- [ ] Criterion 3
|
||||
|
||||
## Verification Steps
|
||||
How to confirm each criterion is met (commands, manual checks, tools).
|
||||
|
||||
## Implementation Guidance
|
||||
Specific patterns, approaches, or constraints.
|
||||
|
||||
## Files Likely Affected
|
||||
- `path/to/file.ts`
|
||||
- `path/to/test.ts`
|
||||
```
|
||||
|
||||
## Writing Effective Legs
|
||||
|
||||
### Objectives
|
||||
|
||||
State exactly what the leg accomplishes in one sentence:
|
||||
|
||||
**Weak**:
|
||||
> Set up the user stuff
|
||||
|
||||
**Strong**:
|
||||
> Create the User model with email, password_hash, and timestamps fields
|
||||
|
||||
The objective should be:
|
||||
- **Specific**: Clear what will be created/modified
|
||||
- **Verifiable**: Can confirm completion by inspection
|
||||
- **Atomic**: One cohesive piece of work
|
||||
|
||||
### Context
|
||||
|
||||
Provide information the AI needs but might not have:
|
||||
|
||||
```markdown
|
||||
## Context
|
||||
|
||||
This project uses Prisma for database access. The existing `prisma/schema.prisma`
|
||||
file contains the Post and Comment models. User will be referenced by these
|
||||
models via foreign keys.
|
||||
|
||||
Authentication uses JWT tokens. The password_hash field will store bcrypt hashes
|
||||
(cost factor 12). The email field must be unique and will be used as the login
|
||||
identifier.
|
||||
```
|
||||
|
||||
Good context includes:
|
||||
- Relevant technology/framework information
|
||||
- Relationship to existing code
|
||||
- Design decisions from the parent flight
|
||||
- Constraints that affect implementation
|
||||
|
||||
### Inputs and Outputs
|
||||
|
||||
Be explicit about state before and after:
|
||||
|
||||
```markdown
|
||||
## Inputs
|
||||
- Prisma schema at `prisma/schema.prisma` with Post and Comment models
|
||||
- No existing User model or authentication
|
||||
|
||||
## Outputs
|
||||
- User model added to Prisma schema
|
||||
- Migration file generated
|
||||
- Migration applied to development database
|
||||
```
|
||||
|
||||
Inputs help the AI understand starting conditions. Outputs define the expected end state.
|
||||
|
||||
### Acceptance Criteria
|
||||
|
||||
Define exactly what "done" means:
|
||||
|
||||
```markdown
|
||||
## Acceptance Criteria
|
||||
- [ ] User model exists in `prisma/schema.prisma`
|
||||
- [ ] User model has fields: id, email, password_hash, created_at, updated_at
|
||||
- [ ] email field has `@unique` attribute
|
||||
- [ ] Migration file exists in `prisma/migrations/`
|
||||
- [ ] `npx prisma migrate status` shows no pending migrations
|
||||
- [ ] TypeScript types generated (`npx prisma generate` succeeds)
|
||||
```
|
||||
|
||||
Acceptance criteria should be:
|
||||
- **Binary**: Either met or not met
|
||||
- **Observable**: Can verify by inspection or test
|
||||
- **Complete**: Nothing else required for "done"
|
||||
|
||||
### Verification Steps
|
||||
|
||||
Tell the AI exactly *how* to confirm each criterion:
|
||||
|
||||
```markdown
|
||||
## Verification Steps
|
||||
- Run `npx prisma migrate status` — should show no pending migrations
|
||||
- Run `npm test` — all tests pass
|
||||
- Open browser to `/users` — page loads without errors
|
||||
- Tab through form fields — focus order matches visual order
|
||||
- Run `npx lighthouse --accessibility` — score ≥ 90
|
||||
```
|
||||
|
||||
Verification steps should be:
|
||||
- **Executable**: Commands or specific actions
|
||||
- **Deterministic**: Same result every time
|
||||
- **Mapped to criteria**: Clear which criterion each step validates
|
||||
|
||||
For accessibility legs, include specific checks:
|
||||
- Keyboard navigation sequences to test
|
||||
- Screen reader commands (e.g., "navigate to main content via skip link")
|
||||
- Automated tool commands (Lighthouse, axe-core)
|
||||
|
||||
### Implementation Guidance
|
||||
|
||||
Provide specific direction when needed:
|
||||
|
||||
```markdown
|
||||
## Implementation Guidance
|
||||
|
||||
Use Prisma's native type for id:
|
||||
```prisma
|
||||
id String @id @default(cuid())
|
||||
```
|
||||
|
||||
For timestamps, use Prisma's auto-managed fields:
|
||||
```prisma
|
||||
created_at DateTime @default(now())
|
||||
updated_at DateTime @updatedAt
|
||||
```
|
||||
|
||||
Do not add relations to Post/Comment yet—that's a separate leg.
|
||||
```
|
||||
|
||||
Implementation guidance helps when:
|
||||
- Project has specific patterns to follow
|
||||
- There are multiple valid approaches (pick one)
|
||||
- Constraints aren't obvious from context
|
||||
|
||||
### Files Likely Affected
|
||||
|
||||
Help the AI know where to look:
|
||||
|
||||
```markdown
|
||||
## Files Likely Affected
|
||||
- `prisma/schema.prisma` - Add User model
|
||||
- `prisma/migrations/*` - New migration file (generated)
|
||||
```
|
||||
|
||||
This isn't prescriptive—the AI might touch other files. It's a starting point for orientation.
|
||||
|
||||
## Leg Lifecycle
|
||||
|
||||
Legs progress through defined states:
|
||||
|
||||
### States
|
||||
|
||||
```
|
||||
planning ──► ready ──► in-flight ──► landed ──► completed
|
||||
│
|
||||
└──► aborted
|
||||
```
|
||||
|
||||
**planning**
|
||||
Leg is being designed. Acceptance criteria and implementation guidance being defined.
|
||||
|
||||
**ready**
|
||||
Leg design approved. Ready for implementation.
|
||||
|
||||
**in-flight**
|
||||
AI agent actively working on implementation.
|
||||
|
||||
**landed**
|
||||
Implementation complete. Flight log updated. Ready for review.
|
||||
|
||||
**completed**
|
||||
Review passed. Acceptance criteria confirmed met.
|
||||
|
||||
**aborted**
|
||||
Leg cancelled. Changes are rolled back. Document the reason in the flight log.
|
||||
|
||||
### State Transitions
|
||||
|
||||
| From | To | Trigger |
|
||||
|------|----|---------|
|
||||
| planning | ready | Design review passes |
|
||||
| ready | in-flight | Developer begins work |
|
||||
| in-flight | landed | Developer reports completion |
|
||||
| in-flight | aborted | Cannot proceed, changes rolled back |
|
||||
| landed | completed | Review passes |
|
||||
| landed | in-flight | Issues found, needs fixes |
|
||||
|
||||
Note: Legs may only be modified while in `planning` state. Once `in-flight`, create new legs instead of modifying existing ones.
|
||||
|
||||
## Patterns for AI Consumption
|
||||
|
||||
### Be Explicit, Not Implicit
|
||||
|
||||
**Implicit** (requires inference):
|
||||
> Add validation to the email field
|
||||
|
||||
**Explicit** (no inference needed):
|
||||
> Add email validation: must be non-empty, valid email format (use validator library's isEmail), maximum 255 characters. Return 400 status with `{ error: "Invalid email format" }` on failure.
|
||||
|
||||
### Provide Examples
|
||||
|
||||
When patterns might be unclear, show don't tell:
|
||||
|
||||
```markdown
|
||||
## Implementation Guidance
|
||||
|
||||
Follow the existing controller pattern:
|
||||
|
||||
```typescript
|
||||
// Example from PostController
|
||||
export async function createPost(req: Request, res: Response) {
|
||||
const { title, content } = req.body;
|
||||
|
||||
if (!title) {
|
||||
return res.status(400).json({ error: "Title is required" });
|
||||
}
|
||||
|
||||
const post = await prisma.post.create({
|
||||
data: { title, content, authorId: req.user.id }
|
||||
});
|
||||
|
||||
return res.status(201).json(post);
|
||||
}
|
||||
```
|
||||
|
||||
Apply this pattern to the registration endpoint.
|
||||
```
|
||||
|
||||
### State Constraints Clearly
|
||||
|
||||
Don't bury constraints in prose:
|
||||
|
||||
**Buried**:
|
||||
> Create the endpoint and make sure it handles errors properly and validates input and also we're using Express and the response should be JSON.
|
||||
|
||||
**Clear**:
|
||||
```markdown
|
||||
## Constraints
|
||||
- Framework: Express.js
|
||||
- Response format: JSON
|
||||
- Error handling: Return appropriate HTTP status codes
|
||||
- Validation: Validate all input before processing
|
||||
```
|
||||
|
||||
### Link to Flight for Context
|
||||
|
||||
When details would be redundant, reference the parent:
|
||||
|
||||
```markdown
|
||||
## Context
|
||||
|
||||
See [parent flight](../flight.md) for:
|
||||
- Authentication approach (JWT tokens)
|
||||
- Session duration decisions
|
||||
- Error response format standards
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Too Large
|
||||
|
||||
If a leg takes more than a few hours, it's probably too big. Signs:
|
||||
- Multiple independent pieces of functionality
|
||||
- Would benefit from intermediate checkpoints
|
||||
- Hard to write clear acceptance criteria
|
||||
|
||||
Split into smaller legs.
|
||||
|
||||
### Too Small
|
||||
|
||||
If a leg is trivial, it adds overhead without value. Signs:
|
||||
- Single line change
|
||||
- No meaningful acceptance criteria
|
||||
- Part of a larger atomic operation
|
||||
|
||||
Combine with related work.
|
||||
|
||||
### Ambiguous Acceptance Criteria
|
||||
|
||||
If criteria require judgment, they're not criteria:
|
||||
|
||||
**Ambiguous**: "Code is clean and readable"
|
||||
**Specific**: "Functions are under 50 lines, no eslint warnings"
|
||||
|
||||
**Ambiguous**: "Error handling is good"
|
||||
**Specific**: "All async operations wrapped in try/catch, errors logged with context"
|
||||
|
||||
### Missing Context
|
||||
|
||||
AI agents don't have your mental model. Include:
|
||||
- Why this approach (from flight decisions)
|
||||
- How this fits with existing code
|
||||
- What patterns to follow
|
||||
- What to avoid
|
||||
|
||||
## Relationship to Flight
|
||||
|
||||
Legs are generated from flights. The flight provides:
|
||||
- Technical approach
|
||||
- Design decisions
|
||||
- Overall context
|
||||
|
||||
Legs provide:
|
||||
- Specific implementation steps
|
||||
- Explicit acceptance criteria
|
||||
- Focused scope
|
||||
|
||||
A flight might generate many legs:
|
||||
|
||||
```
|
||||
Flight: User Registration Flow
|
||||
├── Leg: create-user-model
|
||||
├── Leg: registration-endpoint
|
||||
├── Leg: email-validation
|
||||
├── Leg: password-hashing
|
||||
├── Leg: registration-tests
|
||||
└── Leg: registration-docs
|
||||
```
|
||||
|
||||
## Immutability Principle
|
||||
|
||||
Once a leg is `in-flight`, don't modify it. If requirements change:
|
||||
|
||||
1. Mark the current leg as aborted (changes rolled back)
|
||||
2. Create a new leg with updated requirements
|
||||
3. Reference the old leg for context
|
||||
|
||||
This preserves history and prevents confusion about what the AI was asked to do.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Workflow](workflow.md) — See the complete mission → flight → leg flow
|
||||
- [Flights](flights.md) — Understand where legs come from
|
||||
Reference in New Issue
Block a user