Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ This file provides guidance to Codex (Codex.ai/code) when working with code in t
- Use TypeScript strict mode
- Always follow best practices
- Write self-documenting code: for complex functions, describe purpose, expected inputs, and expected outputs above the function
- In `lib/platform/`, prefer one primary action per file. Use noun directories and verb file names, and add a short boundary comment above the main exported function covering purpose, expected inputs/preconditions, expected outputs/guarantees, and what is out of scope.
- Use functional components with hooks

### Naming Conventions
Expand All @@ -52,6 +53,7 @@ This file provides guidance to Codex (Codex.ai/code) when working with code in t
- Database tables: PascalCase (Prisma models)
- API routes: kebab-case
- Files: kebab-case
- In `lib/platform/`, file names should usually be action-oriented verbs such as `create-project-with-sandbox`, `find-installation-repository`, or `get-user-default-namespace`, rather than vague names like `shared` or `helpers`.

### Component Organization
- **Route-specific components**: Place in `_components/` directory under the route folder
Expand Down
88 changes: 66 additions & 22 deletions docs/architecture-evolution.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,30 +129,32 @@ This layer should be the only place that knows provider-specific protocol detail

## Ideal Repository Shape

The repository should gradually move toward something like this:
The repository should gradually move toward a platform-shaped layout, with
`lib/platform/` acting as the main container for control-plane code:

```text
app/
Framework entrypoints only

lib/
domain/
control/
commands/
queries/
persistence/
orchestrators/
resources/
tasks/
executors/
k8s/
sandbox/
deploy/
integrations/
github/
ttyd/
k8s/
aiproxy/
platform/
control/
commands/
queries/
persistence/
orchestrators/
resources/
tasks/
executors/
k8s/
sandbox/
deploy/
integrations/
github/
ttyd/
k8s/
aiproxy/
policies/
shared/
```
Expand Down Expand Up @@ -206,7 +208,7 @@ Typical examples:

This is the layer that turns interaction into durable state changes.

### `lib/persistence/`
### `lib/platform/persistence/`

Should contain:

Expand All @@ -215,9 +217,11 @@ Should contain:
- lock management
- state transition persistence

This corresponds closely to what `lib/repo/` does today, but with a name that better reflects its role in a control-plane system.
This corresponds closely to what `lib/repo/` does today, but relocated under
`platform/` so the control plane and its persistence boundaries live in one
coherent top-level area.

### `lib/orchestrators/`
### `lib/platform/orchestrators/`

Should contain:

Expand All @@ -230,7 +234,7 @@ This layer is currently spread across `jobs/` and `events/`.

Long term, the code should make it easy to inspect one workflow in one place, instead of hopping across multiple implementation-mechanism directories.

### `lib/executors/`
### `lib/platform/executors/`

Should contain:

Expand All @@ -247,7 +251,7 @@ The key separation is:
- orchestrators decide whether to run
- executors perform the work

### `lib/integrations/`
### `lib/platform/integrations/`

Should contain:

Expand Down Expand Up @@ -307,6 +311,46 @@ It is to make the codebase reflect the platform's actual conceptual boundaries:
- execution
- external integration

### Rule 6: Prefer one primary platform action per file

Within `lib/platform/`, prefer files that exist to express one primary platform action.

Examples:

- `create-project-from-github.ts`
- `create-clone-repository-task.ts`
- `find-installation-repository.ts`
- `get-user-default-namespace.ts`

This improves scanability. A reader should be able to infer the main responsibility
of a file from its name before opening it.

### Rule 7: Use noun directories and verb file names

Within `lib/platform/`:

- directories should describe the boundary or subsystem
- files should describe the primary action they perform

Examples:

- good directory names: `control`, `persistence`, `integrations`, `project-task`
- good file names: `create-project-with-sandbox`, `create-clone-repository-task`, `find-github-installation-by-id`
- weaker file names: `shared`, `github`, `repository-access`, `user-namespace`

### Rule 8: Primary platform functions must carry boundary comments

If a file in `lib/platform/` exists to perform one primary action, its main exported
function should have a short comment that explains:

- purpose
- expected inputs or preconditions
- expected outputs or guarantees
- what is explicitly out of scope

The goal is not comment volume. The goal is to make the file's architectural role
obvious without reading the full implementation.

## Suggested Migration Strategy

The next phase should be gradual.
Expand Down
61 changes: 61 additions & 0 deletions docs/prds/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# PRDs

This directory stores implementation-facing product requirement documents for the
current Fulling codebase.

## What belongs here

Put documents here when they define product behavior that directly affects:

- control-plane state
- UI-visible status semantics
- retry behavior
- persistence requirements
- API or workflow expectations for a concrete feature

Examples:

- import project control flow
- deploy project workflow
- install skill behavior
- database creation UX and state semantics

## What does not belong here

Do not put high-level strategy, roadmap thinking, or long-range architecture vision here.
Those should stay in the handbook project space.

Recommended split:

- `handbook/projects/fulling/`
- vision
- roadmap
- version plans
- postmortems
- architecture direction
- `docs/prds/`
- implementation-facing feature requirements for the repository

## Naming

- One PRD per feature or workflow
- Use stable kebab-case file names
- Prefer names like `import-project-control-flow.md`

## Suggested PRD structure

Each PRD should usually include:

1. Goal
2. Scope
3. Success semantics
4. Failure semantics
5. State requirements
6. UI requirements
7. Retry behavior
8. Persistence requirements
9. Non-goals

## Current PRDs

- [Import Project Control Flow](./import-project-control-flow.md)
164 changes: 164 additions & 0 deletions docs/prds/import-project-control-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
# Import Project Control Flow

Status: Draft

## Goal

Define the product behavior and control-plane semantics for importing a GitHub
repository as a Fulling project.

This PRD exists to clarify what "success" means for:

- project creation
- sandbox creation
- repository cloning
- import failure handling

## Scope

This document covers the current import flow for:

- creating a project from a GitHub repository
- creating the initial sandbox for that project
- cloning the selected repository into the sandbox
- representing clone failure without rolling back the project

This document does not define future repository analysis, skill installation, or
deploy automation after import.

## User Intent

When a user imports a project from GitHub, the system receives two requested outcomes:

1. Create and start a sandbox for the project
2. Clone the selected GitHub repository into that sandbox

These two outcomes are related, but they are not treated as a single all-or-nothing
product success condition.

## Success Semantics

### Project creation success

A project is considered successfully created when its sandbox is successfully created
and reaches a runnable state.

This means:

- if sandbox creation succeeds, project creation succeeds
- project success is not blocked by repository clone failure

### Import transaction success

The import transaction is considered successful only when the repository is cloned
successfully into the sandbox.

## Failure Semantics

### Sandbox creation failure

If the sandbox fails to reach a runnable state, project creation is considered failed.

### Repository clone failure

If the sandbox succeeds but repository cloning fails, the system must:

- keep the project
- keep the sandbox
- mark the import transaction as failed
- preserve the GitHub association metadata on the project

Clone failure does not roll back the project.

Examples of clone failure include:

- repository does not exist
- repository access is denied
- clone operation times out
- GitHub access token or upstream operation fails

## Current UX Requirements

For the current stage of the product:

- the user should still land in a usable project with an empty sandbox
- no dedicated import-failure modal is required yet
- the system should preserve existing code paths as much as possible

## Status Requirements

The system should represent two layers of status:

1. Project resource status
2. Import transaction status

For the current product behavior:

- project status may become `RUNNING`
- import may independently become `IMPORT_FAILED`

The intended current UI meaning is:

- `RUNNING + IMPORT FAILED`

This combination means:

- the sandbox is available
- the project exists and is usable
- the requested repository import did not complete successfully

## Retry Behavior

Repository clone should automatically retry up to 3 times, matching the current system behavior.

Requirements:

- retries are automatic
- no manual retry UX is required in this phase
- exhausting retries should leave the project intact and mark import as failed

## Persistence Requirements

The system must persist enough state to represent:

- that the project exists
- that the sandbox exists
- that the project was created from GitHub
- that the clone task was attempted
- whether the clone task eventually succeeded or failed

If clone fails, the database must still clearly reflect:

- project creation succeeded
- import did not succeed

## GitHub Metadata Requirements

If the repository later becomes unavailable or permissions change, the project should
continue to retain its GitHub association metadata.

This means clone failure or later repository access loss should not automatically clear:

- GitHub installation reference
- GitHub repository ID
- GitHub repository full name
- default branch metadata

## Non-Goals

This PRD does not define:

- a new import intent model
- a dedicated import failure modal
- post-import repository analysis
- skill installation after import
- deployment after import
- new manual retry workflows

## Implementation Notes

Current implementation should preserve this product contract:

- project creation success is anchored to sandbox success
- clone failure is visible as an import failure, not as project creation failure
- import logic may fail independently after the project already exists
Loading
Loading