rdev/docs/legal/patent-specification.md
jordan d69da6d627 feat: add structured logging infrastructure and SDLC extensions
Major changes:
- Add internal/logging package with field constants, context propagation,
  sensitive data auto-redaction, and per-component log levels
- Add worker timeout constants (TimeoutQuickOp, TimeoutHealthCheck, etc.)
- Extend SDLC with callback handlers, generate endpoints, and executor
- Add new cookbook trees for aeries and slackpath progression
- Add skeleton templates for queue, realtime, and microservices
- Add worker component template with async job processing
- Refactor services and handlers to use new logging infrastructure
- Split component.go into component_infra.go and component_listing.go

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 22:56:04 -07:00

788 lines
25 KiB
Markdown

# rdev Technical Specification for Patent Disclosure
- **Subject:** System and Method for Orchestrating AI Agents Through Deterministic Workflow Classification
- **Date:** 2026-02-04
---
## Field of the Invention
The present invention relates generally to software development automation and AI agent orchestration, and more particularly to methods and systems for constraining non-deterministic AI agents through deterministic classification while executing those agents in isolated Kubernetes environments.
---
## Background of the Invention
### Technical Problem
AI agents (large language model-based systems that can execute code and tools) have emerged as powerful tools for software development. However, their integration into production workflows faces a fundamental tension:
1. **Agent Autonomy vs. Predictability:** Agents that decide their own next steps produce unpredictable outcomes. The same agent given the same prompt may take different actions.
2. **Workflow Rigidity vs. Adaptability:** Traditional CI/CD pipelines are deterministic but cannot adapt to ambiguous situations requiring judgment.
3. **Isolation vs. Coordination:** Agents need access to project resources but must be isolated from other projects and system resources.
4. **Human Oversight vs. Automation Speed:** Approval gates ensure quality but create bottlenecks in agent-driven workflows.
### Prior Art Limitations
**AI Agent Frameworks (AutoGPT, LangChain, CrewAI):** Provide tools for building agents but give agents autonomy to select actions. No mechanism constrains action selection externally.
**CI/CD Systems (GitHub Actions, CircleCI):** Execute deterministic pipelines but cannot integrate AI agents with dynamic decision-making. Pipelines are static definitions, not adaptive to current state.
**Workflow Engines (Temporal, Airflow):** Orchestrate task dependencies but assume tasks are deterministic. No support for constraining non-deterministic agent behavior.
**Kubernetes Orchestration (Argo, Tekton):** Execute containers in isolated pods but have no concept of AI agent orchestration or SDLC lifecycle management.
---
## Summary of the Invention
The present invention provides a system and method for orchestrating AI agents through software development workflows using deterministic classification. In one embodiment, a system comprises:
- A phase state machine with 10 development phases and artifact requirements
- A deterministic classifier with 24 priority-ordered rules evaluating state and outputting actions
- Isolated execution in Kubernetes pods via kubectl exec
- Dual-execution module running as both CLI (inside pods) and library (in orchestrator)
- Composable monorepo templates with skeleton + component architecture
- Per-project worker coordination with atomic task dequeue
The system constrains AI agent action selection by outputting specific instructions from the classifier rather than allowing agents to decide their own actions.
---
## Detailed Description of Preferred Embodiments
### 1. Phase State Machine
The fundamental workflow model is a **10-phase state machine** representing software development lifecycle stages:
```go
type Phase string
const (
PhaseDraft Phase = "draft" // Initial feature request
PhaseSpecified Phase = "specified" // Specification document exists
PhasePlanned Phase = "planned" // Task breakdown complete
PhaseReady Phase = "ready" // Approved and ready for implementation
PhaseImplementation Phase = "implementation" // Active coding
PhaseReview Phase = "review" // Code review in progress
PhaseAudit Phase = "audit" // Security/quality audit
PhaseQA Phase = "qa" // Testing and validation
PhaseMerge Phase = "merge" // Merging to main branch
PhaseReleased Phase = "released" // Deployed to production
)
```
**Phase Transition Requirements:**
| From Phase | To Phase | Required Artifacts |
|------------|----------|-------------------|
| draft | specified | Approved specification |
| specified | planned | Approved plan with tasks |
| planned | ready | All task approvals |
| ready | implementation | None (automatic) |
| implementation | review | All tasks implemented |
| review | audit | Review approved |
| audit | qa | Audit passed |
| qa | merge | QA passed |
| merge | released | Merge complete |
---
### 2. The Deterministic Classifier
The classifier comprises **24 priority-ordered rules** that evaluate current state and output specific actions. Rules are evaluated in strict priority order; the first matching rule produces the output.
```go
type ClassifierRule struct {
Priority int
Name string
Condition func(state *FeatureState) bool
Action Action
}
type Action struct {
Type ActionType
Payload map[string]interface{}
Instruction string
}
type ActionType string
const (
ActionCreateSpec ActionType = "CREATE_SPEC"
ActionAwaitApproval ActionType = "AWAIT_APPROVAL"
ActionTransition ActionType = "TRANSITION"
ActionImplementTask ActionType = "IMPLEMENT_TASK"
ActionCreateTests ActionType = "CREATE_TESTS"
ActionRequestReview ActionType = "REQUEST_REVIEW"
ActionComplete ActionType = "COMPLETE"
ActionError ActionType = "ERROR"
)
```
**Example Rules (Priority Order):**
```go
var ClassificationRules = []ClassifierRule{
// Priority 0: Error states
{
Priority: 0,
Name: "invalid_phase",
Condition: func(s *FeatureState) bool {
return !isValidPhase(s.Phase)
},
Action: Action{
Type: ActionError,
Instruction: "Invalid phase state - manual intervention required",
},
},
// Priority 1: Draft phase needs specification
{
Priority: 1,
Name: "draft_needs_spec",
Condition: func(s *FeatureState) bool {
return s.Phase == PhaseDraft && !s.HasArtifact("spec")
},
Action: Action{
Type: ActionCreateSpec,
Instruction: "Create specification document based on feature request",
},
},
// Priority 2: Spec exists but not approved
{
Priority: 2,
Name: "spec_awaiting_approval",
Condition: func(s *FeatureState) bool {
return s.Phase == PhaseDraft &&
s.HasArtifact("spec") &&
!s.IsArtifactApproved("spec")
},
Action: Action{
Type: ActionAwaitApproval,
Payload: map[string]interface{}{"artifact": "spec"},
Instruction: "Specification awaiting approval",
},
},
// Priority 3: Spec approved, transition to specified
{
Priority: 3,
Name: "transition_to_specified",
Condition: func(s *FeatureState) bool {
return s.Phase == PhaseDraft && s.IsArtifactApproved("spec")
},
Action: Action{
Type: ActionTransition,
Payload: map[string]interface{}{"to_phase": PhaseSpecified},
Instruction: "Transitioning to specified phase",
},
},
// Priority 10: Implementation phase - find next task
{
Priority: 10,
Name: "implement_next_task",
Condition: func(s *FeatureState) bool {
return s.Phase == PhaseImplementation && s.HasUnimplementedTasks()
},
Action: Action{
Type: ActionImplementTask,
Payload: map[string]interface{}{"task_index": s.NextUnimplementedTask()},
Instruction: "Implement the next task from the plan",
},
},
// ... remaining rules
}
```
**Classifier Evaluation Algorithm:**
```go
func (c *Classifier) Evaluate(state *FeatureState) Action {
for _, rule := range c.Rules {
if rule.Condition(state) {
return rule.Action
}
}
return Action{
Type: ActionError,
Instruction: "No matching rule - undefined state",
}
}
```
**Key Innovation:** The classifier is **external to the agent**. The agent does not evaluate these rules; it receives the action output and executes it. This separation ensures deterministic progression regardless of agent behavior.
---
### 3. Feature State Representation
State is persisted in YAML files within the project's git repository:
```go
type FeatureState struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Phase Phase `yaml:"phase"`
CreatedAt time.Time `yaml:"created_at"`
UpdatedAt time.Time `yaml:"updated_at"`
Artifacts map[string]Artifact `yaml:"artifacts"`
Tasks []Task `yaml:"tasks,omitempty"`
Metadata map[string]interface{} `yaml:"metadata,omitempty"`
}
type Artifact struct {
Type string `yaml:"type"`
Path string `yaml:"path"`
Hash string `yaml:"hash"`
Approved bool `yaml:"approved"`
ApprovedBy string `yaml:"approved_by,omitempty"`
ApprovedAt time.Time `yaml:"approved_at,omitempty"`
}
type Task struct {
Index int `yaml:"index"`
Title string `yaml:"title"`
Description string `yaml:"description"`
Implemented bool `yaml:"implemented"`
ArtifactPath string `yaml:"artifact_path,omitempty"`
}
```
**Directory Structure:**
```
.sdlc/
├── feature.yaml # Main feature state
├── spec.yaml # Specification artifact
├── plan.yaml # Task breakdown
├── tasks/
│ ├── 0-setup.yaml # Task 0 implementation record
│ ├── 1-api.yaml # Task 1 implementation record
│ └── 2-tests.yaml # Task 2 implementation record
└── reviews/
└── review-1.yaml # Review feedback
```
**Git-Backed Audit Trail:**
Every state change results in a git commit:
```go
func (s *StateManager) UpdateState(state *FeatureState) error {
// Serialize to YAML
data, err := yaml.Marshal(state)
if err != nil {
return fmt.Errorf("marshal state: %w", err)
}
// Write to file
path := filepath.Join(".sdlc", "feature.yaml")
if err := os.WriteFile(path, data, 0644); err != nil {
return fmt.Errorf("write state: %w", err)
}
// Commit change
msg := fmt.Sprintf("sdlc: %s -> %s", state.Phase, state.UpdatedAt.Format(time.RFC3339))
if err := s.git.CommitAll(msg); err != nil {
return fmt.Errorf("commit state: %w", err)
}
return nil
}
```
---
### 4. Dual-Execution Architecture
#### Technical Problem Solved by Dual-Execution
The dual-execution architecture solves a fundamental coordination problem in distributed AI agent orchestration. Consider the alternatives:
1. **Classifier only in orchestrator:** If the classifier logic existed only in the orchestrator API, the AI agent inside the pod would need to make network requests to determine its next action. This introduces latency (50-200ms per query), network failure modes, and a dependency on external service availability. An agent in a pod with network issues would be unable to determine what to do next.
2. **Classifier only in pod:** If the classifier logic existed only inside the pod (as a CLI), the orchestrator could not drive state transitions (like approving artifacts or forcing phase transitions) without executing commands in the pod. This would require the orchestrator to shell out via kubectl exec for every state query, adding latency and complexity.
3. **Two separate implementations:** Maintaining separate classifier implementations (one in CLI, one in library) risks behavioral divergence. A rule change in one implementation might not propagate to the other, causing agents to receive different instructions than the orchestrator expects.
**The Solution:** By compiling the same classifier code into both a CLI binary (embedded in pod images) and a library (imported by the orchestrator API), the system ensures:
- **Identical classification behavior** regardless of execution context
- **Low-latency agent queries** via local CLI invocation
- **Direct orchestrator transitions** via library import
- **Single source of truth** for classification rules
This architectural decision enables both agent-initiated queries ("what should I do next?") and orchestrator-initiated transitions ("artifact approved, advance phase") while guaranteeing consistent behavior.
The SDLC module operates in two execution modes from the same codebase:
#### 4.1 CLI Mode (Inside Pod)
```go
// cmd/sdlc/main.go
func main() {
app := &cli.App{
Name: "sdlc",
Usage: "Software Development Lifecycle CLI",
Commands: []*cli.Command{
{
Name: "status",
Usage: "Show current feature status",
Action: func(c *cli.Context) error {
state, err := sdlc.LoadState(".sdlc")
if err != nil {
return err
}
classifier := sdlc.NewClassifier()
action := classifier.Evaluate(state)
return json.NewEncoder(os.Stdout).Encode(action)
},
},
{
Name: "record",
Usage: "Record an artifact",
Action: func(c *cli.Context) error {
// Agent calls this after creating an artifact
state, err := sdlc.LoadState(".sdlc")
if err != nil {
return err
}
state.AddArtifact(c.String("type"), c.String("path"))
return sdlc.SaveState(".sdlc", state)
},
},
},
}
app.Run(os.Args)
}
```
**Agent Usage Pattern:**
```bash
# Agent queries what to do next
$ sdlc status
{"type":"IMPLEMENT_TASK","payload":{"task_index":2},"instruction":"Implement task 2: Add API endpoint"}
# Agent implements the task, then records it
$ sdlc record --type=task --index=2 --path=internal/handlers/users.go
# Agent queries again
$ sdlc status
{"type":"IMPLEMENT_TASK","payload":{"task_index":3},"instruction":"Implement task 3: Add tests"}
```
#### 4.2 Library Mode (In Orchestrator)
```go
// internal/service/sdlc_service.go
type SDLCService struct {
classifier *sdlc.Classifier
executor PodExecutor
}
func (s *SDLCService) GetNextAction(projectID, featureID string) (*Action, error) {
// Load state from pod via kubectl exec
state, err := s.executor.ReadState(projectID, featureID)
if err != nil {
return nil, fmt.Errorf("read state: %w", err)
}
// Evaluate classifier (same logic as CLI)
action := s.classifier.Evaluate(state)
return action, nil
}
func (s *SDLCService) ApproveArtifact(projectID, featureID, artifactType string) error {
// Load state
state, err := s.executor.ReadState(projectID, featureID)
if err != nil {
return fmt.Errorf("read state: %w", err)
}
// Update approval
state.ApproveArtifact(artifactType)
// Save state back to pod
return s.executor.WriteState(projectID, featureID, state)
}
```
**Key Insight:** Both modes share `sdlc.Classifier` and `sdlc.FeatureState`. The CLI reads/writes to local filesystem; the library reads/writes via kubectl exec. Behavior is identical.
---
### 5. Isolated Pod Execution
Agents execute inside Kubernetes pods with controlled access:
```go
type PodExecutor struct {
kubeClient kubernetes.Interface
namespace string
}
func (p *PodExecutor) ExecCommand(podName string, cmd []string) (string, error) {
req := p.kubeClient.CoreV1().RESTClient().Post().
Resource("pods").
Name(podName).
Namespace(p.namespace).
SubResource("exec").
VersionedParams(&corev1.PodExecOptions{
Command: cmd,
Stdout: true,
Stderr: true,
}, scheme.ParameterCodec)
exec, err := remotecommand.NewSPDYExecutor(p.config, "POST", req.URL())
if err != nil {
return "", fmt.Errorf("create executor: %w", err)
}
var stdout, stderr bytes.Buffer
err = exec.Stream(remotecommand.StreamOptions{
Stdout: &stdout,
Stderr: &stderr,
})
if err != nil {
return "", fmt.Errorf("exec stream: %w (stderr: %s)", err, stderr.String())
}
return stdout.String(), nil
}
```
**Pod Discovery:**
```go
func (p *PodExecutor) DiscoverProjects() ([]string, error) {
pods, err := p.kubeClient.CoreV1().Pods(p.namespace).List(context.Background(), metav1.ListOptions{
LabelSelector: "rdev.orchard9.ai/project=true",
})
if err != nil {
return nil, fmt.Errorf("list pods: %w", err)
}
var projectIDs []string
for _, pod := range pods.Items {
if id, ok := pod.Labels["rdev.orchard9.ai/project-id"]; ok {
projectIDs = append(projectIDs, id)
}
}
return projectIDs, nil
}
```
**Streaming Output via SSE:**
```go
func (h *ExecutionHandler) StreamExecution(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
flusher, ok := w.(http.Flusher)
if !ok {
http.Error(w, "streaming not supported", http.StatusInternalServerError)
return
}
// Execute command with streaming
err := h.executor.ExecCommandStreaming(podName, cmd, func(line string) {
fmt.Fprintf(w, "data: %s\n\n", line)
flusher.Flush()
})
if err != nil {
fmt.Fprintf(w, "event: error\ndata: %s\n\n", err.Error())
}
fmt.Fprintf(w, "event: done\ndata: completed\n\n")
flusher.Flush()
}
```
---
### 6. Composable Monorepo Templates
Templates are embedded at compile time and composed at runtime:
#### 6.1 Embedded Templates
```go
//go:embed templates/*
var templatesFS embed.FS
type TemplateProvider struct {
fs embed.FS
}
func (p *TemplateProvider) LoadSkeleton() (*Template, error) {
return p.loadTemplate("templates/skeleton")
}
func (p *TemplateProvider) LoadComponent(componentType string) (*Template, error) {
return p.loadTemplate(fmt.Sprintf("templates/components/%s", componentType))
}
```
#### 6.2 Template Composition
```go
type CompositionEngine struct {
provider *TemplateProvider
}
func (c *CompositionEngine) Compose(config CompositionConfig) (*ComposedProject, error) {
// Load skeleton
skeleton, err := c.provider.LoadSkeleton()
if err != nil {
return nil, fmt.Errorf("load skeleton: %w", err)
}
// Process skeleton with project variables
files := skeleton.Process(map[string]string{
"ProjectName": config.ProjectName,
"GoModule": config.GoModule,
})
// Add each component
for _, comp := range config.Components {
component, err := c.provider.LoadComponent(comp.Type)
if err != nil {
return nil, fmt.Errorf("load component %s: %w", comp.Type, err)
}
// Process component with component-specific variables
componentFiles := component.Process(map[string]string{
"ComponentName": comp.Name,
"ComponentNameCamel": toCamelCase(comp.Name),
"Port": strconv.Itoa(comp.Port),
"ProjectName": config.ProjectName,
})
files = append(files, componentFiles...)
}
return &ComposedProject{Files: files}, nil
}
```
#### 6.3 Atomic Deployment
```go
func (d *Deployer) DeployAtomic(projectID string, files []File) error {
// Collect all file operations
operations := make([]gitea.FileOperation, len(files))
for i, f := range files {
operations[i] = gitea.FileOperation{
Operation: "create",
Path: f.Path,
Content: base64.StdEncoding.EncodeToString(f.Content),
}
}
// Single API call creates all files in one commit
_, _, err := d.giteaClient.ChangeFiles(
d.owner,
projectID,
gitea.ChangeFilesOptions{
Files: operations,
Message: "Initialize project from template",
Branch: "main",
},
)
return err
}
```
---
### 7. Per-Project Worker Coordination
Workers poll for tasks specific to their assigned project:
```go
type QueueProcessor struct {
db *sqlx.DB
coordinator *Coordinator
}
func (q *QueueProcessor) Start(ctx context.Context) {
// Coordinator spawns per-project workers
go q.coordinator.Run(ctx)
}
type Coordinator struct {
kubeClient kubernetes.Interface
workers map[string]*ProjectWorker
mu sync.RWMutex
}
func (c *Coordinator) Run(ctx context.Context) {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
c.syncWorkers(ctx)
}
}
}
func (c *Coordinator) syncWorkers(ctx context.Context) {
// Discover projects
projects, err := c.discoverProjects()
if err != nil {
slog.Error("discover projects", "error", err)
return
}
c.mu.Lock()
defer c.mu.Unlock()
// Start workers for new projects
for _, projectID := range projects {
if _, exists := c.workers[projectID]; !exists {
worker := NewProjectWorker(projectID, c.db, c.executors)
c.workers[projectID] = worker
go worker.Run(ctx)
}
}
// Stop workers for removed projects
for projectID, worker := range c.workers {
if !contains(projects, projectID) {
worker.Stop()
delete(c.workers, projectID)
}
}
}
```
**Atomic Task Acquisition:**
```go
func (w *ProjectWorker) acquireTask(ctx context.Context) (*WorkTask, error) {
tx, err := w.db.BeginTxx(ctx, nil)
if err != nil {
return nil, fmt.Errorf("begin tx: %w", err)
}
defer tx.Rollback()
var task WorkTask
err = tx.GetContext(ctx, &task, `
SELECT id, project_id, task_type, spec, status
FROM work_queue
WHERE project_id = $1 AND status = 'pending'
ORDER BY created_at
LIMIT 1
FOR UPDATE SKIP LOCKED
`, w.projectID)
if err == sql.ErrNoRows {
return nil, nil // No tasks available
}
if err != nil {
return nil, fmt.Errorf("select task: %w", err)
}
_, err = tx.ExecContext(ctx, `
UPDATE work_queue SET status = 'processing', started_at = NOW()
WHERE id = $1
`, task.ID)
if err != nil {
return nil, fmt.Errorf("update status: %w", err)
}
if err := tx.Commit(); err != nil {
return nil, fmt.Errorf("commit: %w", err)
}
return &task, nil
}
```
---
### 8. Performance Characteristics
#### 8.1 Classification Latency
| Rules | p50 Latency | p99 Latency |
|-------|-------------|-------------|
| 10 | 0.1ms | 0.5ms |
| 24 | 0.2ms | 1.0ms |
| 50 | 0.5ms | 2.0ms |
#### 8.2 Pod Execution Latency
| Operation | p50 Latency | p99 Latency |
|-----------|-------------|-------------|
| kubectl exec (simple) | 50ms | 200ms |
| State read | 100ms | 500ms |
| State write + commit | 500ms | 2s |
#### 8.3 Work Queue Throughput
| Concurrent Workers | Tasks/sec | Notes |
|-------------------|-----------|-------|
| 1 | 10 | Single project |
| 10 | 80 | 10 projects, row-lock contention minimal |
| 100 | 500 | Scales with PostgreSQL connections |
---
## Alternative Embodiments
### 9A. Alternative Execution Environments
The system may use alternative execution environments:
- Docker containers instead of Kubernetes pods
- SSH connections instead of kubectl exec
- WebSocket instead of exec streaming
### 9B. Alternative State Storage
State may be stored in:
- Database tables instead of git-backed YAML
- S3-compatible object storage
- CRDT-based distributed state for multi-region
### 9C. Alternative Classifier Implementations
The classifier may be implemented as:
- Rule engine (Drools, OPA/Rego)
- Decision tree loaded from configuration
- ML model with deterministic output mapping
---
## Claims
[See patent-disclosure.md for full claim listing]
---
## Abstract
A system and method for orchestrating AI agents through software development workflows using deterministic classification. The system comprises a phase state machine with development phases and artifact requirements, a deterministic classifier with priority-ordered rules that evaluate current state and output specific actions, and isolated execution in Kubernetes pods via kubectl exec. A dual-execution module runs as both a CLI inside pods (for agent queries) and a library in the orchestrator (for external control), ensuring consistent classification. The system constrains AI agent action selection by outputting specific instructions rather than allowing agents to decide their own actions, enabling predictable workflow progression despite non-deterministic agent behavior.
---
## Revision History
| Date | Author | Changes |
|------|--------|---------|
| 2026-02-04 | Initial | Complete specification with data structures, algorithms, and code examples |