agent/pkg/lib/workspace/default/CODEX.md.tmpl
Virgil 3c2575f45b fix(ax): remove proc.go wrapper layer
Co-Authored-By: Virgil <virgil@lethean.io>
2026-03-30 15:48:21 +00:00

167 lines
4.6 KiB
Cheetah

# CODEX.md
Instructions for Codex when working in this workspace.
Read these files in order:
1. `CODEX.md`
2. `.core/reference/RFC-025-AGENT-EXPERIENCE.md`
3. `.core/reference/docs/RFC.md`
4. `AGENTS.md` if present
## Overview
This workspace follows RFC-025 Agent Experience (AX) design. Prefer predictable names, named Actions, Core primitives, usage-example comments, and behavioural tests over terse APIs. Use `.core/reference/*.go` as the local implementation reference.
## Core Registration Pattern
Register services through `core.New` and `WithService`, not ad hoc globals.
```go
c := core.New(
core.WithOption("name", "my-service"),
core.WithService(myservice.Register),
)
c.Run()
```
## Service Pattern
Services should be Result-native and register capabilities by name.
```go
func Register(c *core.Core) core.Result {
svc := &Service{
ServiceRuntime: core.NewServiceRuntime(c, Options{}),
}
return core.Result{Value: svc, OK: true}
}
func (s *Service) OnStartup(ctx context.Context) core.Result {
c := s.Core()
c.Action("workspace.create", s.handleWorkspaceCreate)
c.Task("workspace.bootstrap", core.Task{
Steps: []core.Step{
{Action: "workspace.create"},
},
})
return core.Result{OK: true}
}
func (s *Service) OnShutdown(ctx context.Context) core.Result {
return core.Result{OK: true}
}
```
## Core Accessors
| Accessor | Purpose |
|----------|---------|
| `c.Options()` | Input configuration |
| `c.Config()` | Runtime settings and feature flags |
| `c.Data()` | Embedded assets |
| `c.Fs()` | Filesystem I/O |
| `c.Process()` | Managed process execution |
| `c.API()` | Remote streams and protocol handles |
| `c.Action(name)` | Named callable registration and invocation |
| `c.Task(name)` | Composed Action sequence |
| `c.Entitled(name)` | Permission check |
| `c.RegistryOf(name)` | Cross-cutting registry lookup |
| `c.Cli()` | CLI command framework |
| `c.IPC()` | Message bus |
| `c.Log()` | Structured logging |
| `c.Error()` | Panic recovery |
| `c.I18n()` | Internationalisation |
## Named Actions And Tasks
Actions are the primary communication pattern. Register by name, invoke by name.
```go
c.Action("workspace.create", func(ctx context.Context, opts core.Options) core.Result {
name := opts.String("name")
path := core.JoinPath("/srv/workspaces", name)
return core.Result{Value: path, OK: true}
})
r := c.Action("workspace.create").Run(ctx, core.NewOptions(
core.Option{Key: "name", Value: "alpha"},
))
```
Use Tasks to compose orchestration declaratively.
```go
c.Task("deploy", core.Task{
Steps: []core.Step{
{Action: "docker.build"},
{Action: "docker.push"},
{Action: "deploy.ansible", Async: true},
},
})
```
## Core Primitives
Route recurring concerns through Core primitives instead of the raw standard library.
```go
var fs = (&core.Fs{}).NewUnrestricted()
statusPath := core.JoinPath("/srv/workspaces", "alpha", "status.json")
read := fs.Read(statusPath)
run := c.Process().RunIn(ctx, repoDir, "git", "log", "--oneline", "-20")
if run.OK {
output := core.Trim(run.Value.(string))
core.Print(nil, output)
}
```
## Mandatory Conventions
- Use UK English in comments and docs.
- Use `core.E("pkg.Method", "message", err)` for errors. Never use `fmt.Errorf` or `errors.New`.
- Use `c.Fs()` or a package-level `fs` helper for file I/O. Never use raw `os.ReadFile`, `os.WriteFile`, or `filepath.*`.
- Route external commands through `c.Process()`. Never import `os/exec`.
- Use Core string and path helpers such as `core.Contains`, `core.Trim`, `core.Split`, `core.Concat`, and `core.JoinPath` instead of raw `strings.*` or path concatenation.
- Prefer `core.Result{Value: x, OK: true}` over `(value, error)` pairs in Core-facing code.
- Comments should show HOW with real values, not restate the signature.
- Use predictable names such as `Config`, `Service`, and `Options`; avoid abbreviations.
- Keep paths self-describing. Directory names should tell an agent what they contain.
- Prefer templates for recurring generated files and config shapes.
## AX Quality Gates
Treat these imports as review failures in production Go code:
- `os`
- `os/exec`
- `fmt`
- `log`
- `errors`
- `encoding/json`
- `path/filepath`
- `strings`
- `unsafe`
## Testing
Use AX test naming and keep example coverage close to the source.
```text
TestFile_Function_Good
TestFile_Function_Bad
TestFile_Function_Ugly
```
Where practical, keep one focused `_example_test.go` alongside each source file so the tests double as usage documentation.
## Build & Test
```bash
go build ./...
go test ./... -count=1 -timeout 60s
go vet ./...
```