Skip to content

Commit d7f671b

Browse files
Merge pull request #318 from callmeradical/dev
feat: bundle consolidation, Smithfile, docs rewrite, smithfile-skill
2 parents 7f82138 + 851dd31 commit d7f671b

File tree

14 files changed

+958
-73
lines changed

14 files changed

+958
-73
lines changed

Smithfile

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Smithfile — smith project configuration for autonomous loops
2+
version: 1
3+
4+
runtime:
5+
image: ghcr.io/callmeradical/smith-replica:branch-main
6+
pull_policy: Always
7+
skills_image: ghcr.io/callmeradical/smith-skills:branch-main
8+
skills_pull_policy: Always
9+
10+
provider:
11+
profile: claude-default
12+
13+
max_iterations: 25
14+
15+
env:
16+
GOFLAGS: "-count=1"
17+
CGO_ENABLED: "0"
18+
19+
lifecycle:
20+
startup: "mise install && go mod download"
21+
pre_workflow: "mise run lint"
22+
post_workflow: "go test ./... -short"
23+
on_failure: "go test ./... -short -v 2>&1 | tail -100"
24+
25+
dispositions:
26+
feature:
27+
implement_commands:
28+
- "go build ./..."
29+
- "go test ./... -short"
30+
validate_commands:
31+
- "mise run lint"
32+
implement_prompts:
33+
- "Follow TDD workflow. Write failing tests first."
34+
- "Read the knowledge graph before exploring files."
35+
bug-fix:
36+
diagnose_commands:
37+
- "go test ./... -short -v"
38+
implement_commands:
39+
- "go build ./..."
40+
- "go test ./... -short"
41+
implement_prompts:
42+
- "Reproduce the bug with a failing test before fixing."
43+
refactor:
44+
implement_commands:
45+
- "go build ./..."
46+
- "go test ./... -short"
47+
validate_commands:
48+
- "mise run lint"
49+
implement_prompts:
50+
- "Ensure all existing tests pass before and after refactoring."
51+
- "Do not change public API signatures without updating callers."
52+
53+
build_instructions: |
54+
## Build
55+
go build ./...
56+
57+
## Test
58+
go test ./... -short
59+
go test ./... -short -count=1 # no cache
60+
61+
## Lint
62+
mise run lint
63+
64+
## Full CI (local)
65+
mise run ci:act
66+
67+
## Acceptance Tests
68+
go test ./test/acceptance/ -v
69+
70+
guardrails: |
71+
- ALWAYS use etcd as the state backend. NEVER introduce a second state store for loop lifecycle state.
72+
- ALWAYS use TransitionEngine for loop state mutations with CAS semantics.
73+
- ALWAYS validate ingress metadata and environment profiles before loop creation.
74+
- NEVER add provider-specific logic to core code. Use the provider adapter interface.
75+
- ALWAYS coordinate git push + etcd state as a saga (push first, then state update).
76+
- ALWAYS store credentials in Kubernetes Secrets via Doppler. NEVER hardcode secrets.
77+
- NEVER add frontend code to the smith repo. Frontend lives in smith-console.
78+
- ALWAYS deploy via Helm chart. NEVER raw kubectl.
79+
- ALWAYS use mise.toml for tasks. NEVER standalone shell scripts.
80+
- ALWAYS use GitHub App installation tokens (short-lived). NEVER store PATs.
81+
- ALWAYS ensure golangci-lint v2 passes (errcheck, govet, revive, staticcheck).
82+
- ALWAYS write Go acceptance tests in test/acceptance/, NOT bash scripts.
83+
- ALWAYS gate new features behind runtime feature flags.
84+
- ALWAYS register provider runtime commands via provider Registration.
85+
- NEVER add gRPC. Use HTTP/OpenAPI only.
86+
- ALWAYS use Postgres + Garage backend for document storage.
87+
- ALWAYS put backup logic in cmd/smith-backup/, not smith-api.
88+
- NEVER import legacy StateStore in new code. Use TransitionEngine and Collection[T].
89+
- ALWAYS separate app code commits from infra/deployment commits.
90+
- NEVER run tests during worktree agent commits.

docs/architecture/graphify-data-flow.md

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,33 @@ Graphify is the knowledge graph extraction tool that produces a structural AST-b
44

55
## Sequence Diagram
66

7-
See [graphify-lifecycle.mmd](../diagrams/graphify-lifecycle.mmd) for the full lifecycle sequence diagram.
7+
```mermaid
8+
sequenceDiagram
9+
participant Webhook as Push Webhook
10+
participant API as smith-api
11+
participant K8s as Kubernetes
12+
participant Replica as smith-replica
13+
participant Garage as Garage S3
14+
participant Agent
15+
16+
Note over Webhook,API: Background Graph Build
17+
Webhook->>API: push event (default branch)
18+
API->>API: findProjectByRepo()
19+
API->>K8s: dispatch graph_build loop
20+
K8s->>Replica: schedule Job
21+
Replica->>Replica: run graphify (5 min timeout)
22+
Replica->>Garage: store graph.json
23+
24+
Note over Replica,Agent: Loop Pre-Work
25+
K8s->>Replica: schedule implementation loop
26+
Replica->>Garage: fetch cached graph.json
27+
alt cached graph found
28+
Replica->>Replica: write .smith/loop/graph.json
29+
else no cache
30+
Replica->>Replica: run graphify locally
31+
end
32+
Replica->>Agent: prompt includes GRAPH_PATH
33+
```
834

935
## Push Webhook Flow
1036

docs/architecture/smithfile-data-flow.md

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,34 @@ The Smithfile is a YAML configuration file committed to the root of a target rep
44

55
## Sequence Diagram
66

7-
See [smithfile-attachment-flow.mmd](../diagrams/smithfile-attachment-flow.mmd) for the full attachment-time sequence diagram.
7+
```mermaid
8+
sequenceDiagram
9+
participant User
10+
participant GitHubApp as GitHub App
11+
participant API as smith-api
12+
participant GitHubAPI as GitHub API
13+
participant ProjectStore
14+
15+
User->>GitHubApp: attach repo (full_name)
16+
GitHubApp->>API: POST /v1/integrations/github-app/repositories/attach
17+
API->>API: Verify installation connected, repo in scope
18+
19+
API->>GitHubAPI: GET /repos/{owner}/{repo}/contents/Smithfile
20+
21+
alt Smithfile found
22+
API->>API: Parse YAML, Validate, Derive project ID
23+
API->>API: Merge Smithfile into Project
24+
API->>ProjectStore: Upsert project
25+
API->>GitHubAPI: Check GUARDRAILS.md
26+
alt no guardrails
27+
API->>GitHubAPI: Open issue "guardrails missing"
28+
end
29+
API->>User: 200 {repository, project}
30+
else no Smithfile
31+
API->>GitHubAPI: Open issue "Smithfile required"
32+
API->>User: 422 smithfile_required
33+
end
34+
```
835

936
## Attachment-Time Flow
1037

docs/architecture/system-overview.md

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,47 @@
22

33
Smith is a distributed autonomous orchestration platform composed of several microservices coordinating via **etcd**, **Kubernetes**, **PostgreSQL**, and **Garage (S3)**.
44

5+
## Deployment Topology
6+
7+
```mermaid
8+
C4Component
9+
title Smith Deployment Topology
10+
11+
Container_Boundary(api_boundary, "API Layer") {
12+
Component(smith_api, "smith-api", "Go binary", "HTTP API, webhooks, project store")
13+
}
14+
15+
Container_Boundary(control_boundary, "Control Plane") {
16+
Component(smith_core, "smith-core", "Go binary", "Loop orchestrator, K8s Job dispatch")
17+
Component(smith_daemon, "smith-daemon", "Go binary", "Retention cleanup, policy reload")
18+
}
19+
20+
Container_Boundary(worker_boundary, "Worker Pods") {
21+
Component(smith_replica, "smith-replica", "Go binary", "Ephemeral worker, graphify, agent runtime")
22+
}
23+
24+
Container_Boundary(data_boundary, "Data Substrate") {
25+
ComponentDb(etcd, "etcd v3", "KV store", "State machine, locks, journal")
26+
ComponentDb(postgres, "PostgreSQL", "RDBMS", "Document metadata, projects")
27+
ComponentDb(garage, "Garage S3", "Object store", "Blobs, graphs, bundles")
28+
}
29+
30+
Container_Boundary(external_boundary, "External") {
31+
Component(github, "GitHub", "SaaS", "Webhooks, App auth, issues, code push")
32+
}
33+
34+
Rel(smith_api, etcd, "state, journal, anomalies")
35+
Rel(smith_api, postgres, "documents, projects")
36+
Rel(smith_api, garage, "document blobs")
37+
Rel(smith_api, github, "webhooks, tokens, issues")
38+
Rel(smith_core, etcd, "watch loops, acquire locks")
39+
Rel(smith_core, smith_replica, "schedule K8s Jobs")
40+
Rel(smith_daemon, etcd, "prune old records")
41+
Rel(smith_replica, etcd, "read anomaly, write state")
42+
Rel(smith_replica, garage, "cached graphs, bundles")
43+
Rel(smith_replica, github, "clone, push, PR")
44+
```
45+
546
## Core Components
647

748
- **`smith-api`**: The primary gateway for the Console and CLI. Handles authentication, project/provider management, and ingress (GitHub/PRD).
@@ -61,7 +102,7 @@ The **Smithfile** is a YAML file committed to the root of a target repository th
61102

62103
If no Smithfile is found during attachment, smith opens a GitHub issue on the repository with setup instructions and rejects the attachment with `422 smithfile_required`.
63104

64-
See [Smithfile Data Flow](smithfile-data-flow.md) and [smithfile-attachment-flow.mmd](../diagrams/smithfile-attachment-flow.mmd) for details.
105+
See [Smithfile Data Flow](smithfile-data-flow.md) for the full sequence diagram and ERD.
65106

66107
## Knowledge Graph (graphify pre-work)
67108

@@ -75,7 +116,7 @@ Smith integrates **graphify** to produce structural AST-based knowledge graphs o
75116

76117
The graph path is injected into the agent's build prompt via the `GRAPH_PATH` template variable.
77118

78-
See [Graphify Data Flow](graphify-data-flow.md) and [graphify-lifecycle.mmd](../diagrams/graphify-lifecycle.mmd) for details.
119+
See [Graphify Data Flow](graphify-data-flow.md) for the full sequence diagram.
79120

80121
## Guardrails Enforcement (Loop Blocking)
81122

@@ -92,7 +133,24 @@ If neither source provides guardrails, `guardrailsPresent()` returns false and t
92133

93134
When guardrails are present, they are included in the agent's build prompt via `PROJECT_GUARDRAILS_PATH`, `GUARDRAILS_PATH`, and `GUARDRAILS_REF_PATH` template variables. The agent reads these files before making any code edits.
94135

95-
See [guardrails-enforcement.mmd](../diagrams/guardrails-enforcement.mmd) for the flowchart.
136+
```mermaid
137+
flowchart TD
138+
Start([Loop enters implementation stage])
139+
CheckSmithfile{Smithfile guardrails<br/>non-empty?}
140+
Materialize[Materialize to<br/>.smith/loop/project-guardrails.md]
141+
CheckFile{GUARDRAILS.md exists<br/>at repo root?}
142+
Present([Guardrails present])
143+
Block([Block loop<br/>flatline: guardrails-missing])
144+
Deliver[Agent receives constraints<br/>before coding]
145+
146+
Start --> CheckSmithfile
147+
CheckSmithfile -->|non-empty| Materialize
148+
Materialize --> Present
149+
CheckSmithfile -->|empty| CheckFile
150+
CheckFile -->|exists| Present
151+
CheckFile -->|not found| Block
152+
Present --> Deliver
153+
```
96154

97155
## Internal Architecture Docs
98156

0 commit comments

Comments
 (0)