Files
Triple-C/container/mission-control/docs/legs.md
Josh Knapp 2dffef0767
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
Bundle mission-control into Triple-C instead of cloning from GitHub
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>
2026-04-03 09:09:15 -07:00

9.7 KiB

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:

# 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:

## 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:

## 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:

## 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:

## 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:

## Implementation Guidance

Use Prisma's native type for id:
```prisma
id String @id @default(cuid())

For timestamps, use Prisma's auto-managed fields:

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:

## 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

When details would be redundant, reference the parent:

## 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 — See the complete mission → flight → leg flow
  • Flights — Understand where legs come from