Skip to content

Commit f35d72f

Browse files
committed
Rename the ship app to software_factory (ENG-887)
The name now matches what the app does: staged agent work with gates and a journal. Rename the class, app name and durable kinds, MCP tool, directories, routes, prompt paths, and the per-repo config path. A data migration rewrites stored kinds, event app tags, file app tags, and settings keys so history and saved settings survive.
1 parent bfc9a05 commit f35d72f

128 files changed

Lines changed: 647 additions & 507 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎AGENTS.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
Druks runs durable agent apps on DBOS and Postgres. It owns
44
workflow execution, persisted state and events, gates, webhooks, sandbox access,
55
and the shared dashboard. Apps are standalone Python packages
6-
that self-register through the `druks.apps` entry point. `ship` is the
6+
that self-register through the `druks.apps` entry point. `software_factory` is the
77
bundled reference app for coordinating coding agents through GitHub PRs.
88

99
## Read map
@@ -28,7 +28,7 @@ For app-surface changes, inspect the proof app at
2828
## Architectural boundaries
2929

3030
- Keep platform and app ownership explicit. GitHub issue, branch, PR, and
31-
coding-agent policy belongs to `ship`, not to Druks core.
31+
coding-agent policy belongs to `software_factory`, not to Druks core.
3232
- Describe durability precisely: completed durable checkpoints are reused when
3333
orchestration replays, but an interrupted operation may run again. Do not imply
3434
arbitrary-line resume or exactly-once external side effects.
@@ -130,7 +130,7 @@ truth for CI, including the proof-app install phase.
130130
routing, architectural boundaries, and contributor rules.
131131
- Link to one canonical explanation instead of copying it into multiple pages.
132132
- Verify behavioral claims against current source and focused tests. Distinguish
133-
framework capabilities from `ship` behavior and guarantees from policy.
133+
framework capabilities from `software_factory` behavior and guarantees from policy.
134134
- Update this file only when contributor routing, repository structure, commands,
135135
or a load-bearing architectural invariant changes.
136136

‎README.md‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
> before 1.0; `main` and `latest` are edge builds, not stable releases.
1313
1414
Druks is the self-hosted **home for durable agent apps**, running on the
15-
Claude and Codex subscriptions you already pay for. Ship comes bundled:
15+
Claude and Codex subscriptions you already pay for. Software Factory comes bundled:
1616
autonomous software delivery from ticket to reviewed pull request.
1717

1818
An ordinary agent script loses its place when the process dies. A Druks
@@ -46,7 +46,7 @@ described in [the release process](https://github.com/czpython/druks/blob/main/d
4646
Re-running is also the upgrade path. Then follow
4747
[full local setup](https://github.com/czpython/druks/blob/main/docs/full-local.md) to finish in
4848
the dashboard: connect the agent harnesses and the GitHub App the bundled
49-
`ship` app acts through; a standalone app may have different
49+
`software_factory` app acts through; a standalone app may have different
5050
integration requirements.
5151

5252
Or hand the install to a coding agent — paste this into Claude Code, Codex,
@@ -105,9 +105,9 @@ uvx --from druks druks create app night_watch
105105
The generated project root carries an `AGENTS.md` with the contracts and a link
106106
to the authoring guide.
107107

108-
The bundled `ship` app is a concrete example. It coordinates coding
108+
The bundled `software_factory` app is a concrete example. It coordinates coding
109109
agents through tickets and GitHub pull requests, but GitHub PR orchestration is
110-
`ship` behavior—not the definition of Druks.
110+
`software_factory` behavior—not the definition of Druks.
111111

112112
## Documentation
113113

‎backend/druks/agents.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ async def get_timeout(self) -> int:
146146
return min(resolved, MAX_AGENT_TIMEOUT_SECONDS)
147147

148148
async def __call__(self, **context: object) -> Any:
149-
"""Run the agent — ``await Ship.implement(...)`` — as a durable step in the
149+
"""Run the agent — ``await SoftwareFactory.implement(...)`` — as a durable step in the
150150
current workflow and return its parsed output. An agent run is always memoized —
151151
this picks which step does it: its own, or the @step it's already inside.
152152
workflow_id comes from the workflow context, not the caller; everything

‎backend/druks/api/server.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ async def _unhandled_exception_handler(
260260

261261

262262
# Platform-core routers, mounted by hand at their own prefixes. App routers
263-
# (core, ship, usage, …) are discovered and mounted under /api/<app> by load().
263+
# (core, software_factory, usage, …) are discovered and mounted under /api/<app> by load().
264264
# /api sits behind the identity gate except the identity/connection surface and
265265
# the health probe; /_external routes carry their own authentication. The
266266
# boundary test pins the split. The auth and harness-connection routers mount

‎backend/druks/contrib/review/contracts.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from typing import Literal
22

33
from druks.agents import AgentOutput
4-
from druks.contrib.ship.contracts import FindingOutput
4+
from druks.contrib.software_factory.contracts import FindingOutput
55

66

77
class ReviewReport(AgentOutput):

‎backend/druks/contrib/review/routes.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from druks.accounts.dependencies import current_account
44
from druks.accounts.models import Account
55
from druks.contrib.review.workflows import PullRequestReview
6-
from druks.contrib.ship.models import ProjectRepo
6+
from druks.contrib.software_factory.models import ProjectRepo
77

88
router = APIRouter(prefix="/reviews")
99

‎backend/druks/contrib/review/subscribers.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from druks.contrib.review.github import get_review_actor
22
from druks.contrib.review.workflows import PullRequestReview
3-
from druks.contrib.ship.models import ProjectRepo
3+
from druks.contrib.software_factory.models import ProjectRepo
44
from druks.signals import subscribe
55

66

‎backend/druks/contrib/review/workflows.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from druks.contrib.review.app import Review
55
from druks.contrib.review.datastructures import PullRequest
66
from druks.contrib.review.github import get_review_actor
7-
from druks.contrib.ship.models import ProjectRepo
7+
from druks.contrib.software_factory.models import ProjectRepo
88
from druks.core.apis.github import GITHUB
99
from druks.sandbox import repo as _repo
1010
from druks.sandbox.layout import get_github_token_remote_path, get_related_root, get_repo_root
File renamed without changes.

backend/druks/contrib/ship/app.py renamed to backend/druks/contrib/software_factory/app.py

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from druks.agents import Agent
66
from druks.apps import App, AppSettings
7-
from druks.contrib.ship.contracts import (
7+
from druks.contrib.software_factory.contracts import (
88
ContractRevisionOutput,
99
EvaluationOutput,
1010
ImplementationOutput,
@@ -13,9 +13,9 @@
1313
ReviewOutput,
1414
TriageOutput,
1515
)
16-
from druks.contrib.ship.ticketing.base import Tracker
17-
from druks.contrib.ship.ticketing.jira import Jira
18-
from druks.contrib.ship.ticketing.linear import Linear
16+
from druks.contrib.software_factory.ticketing.base import Tracker
17+
from druks.contrib.software_factory.ticketing.jira import Jira
18+
from druks.contrib.software_factory.ticketing.linear import Linear
1919
from druks.core import services
2020
from druks.db import StoredSubject
2121
from druks.doctor import CheckResult
@@ -33,7 +33,7 @@
3333
async def check_tracker_identity() -> CheckResult:
3434
"""Whether the selected tracker's identity is connected. Trackerless is a
3535
choice, not a fault; a selected-but-unconnected tracker is pending setup."""
36-
settings = await Ship.settings()
36+
settings = await SoftwareFactory.settings()
3737
if settings.tracker == "none":
3838
return CheckResult(name="tracker", ok=True, detail="trackerless by choice")
3939
service = {"linear": services.Linear, "jira": services.Jira}[settings.tracker]
@@ -48,18 +48,22 @@ async def check_tracker_identity() -> CheckResult:
4848
)
4949

5050

51-
class Ship(App):
52-
name = "ship"
51+
class SoftwareFactory(App):
52+
name = "software_factory"
5353
# These tables (projects, work_items, ...) are already unprefixed in core's
5454
# migration history, so they must stay that way.
5555
prefix_tables = False
56-
icon = "ship"
56+
icon = "factory"
5757
description = (
5858
"Each stage of the build pipeline runs as its own agent. An agent runs its own "
5959
"model, or inherits its harness default — the backend dispatches the harness "
6060
"from the model you pick."
6161
)
62-
navigation = [("/ship", "active"), ("/ship/history", "history"), ("/ship/projects", "projects")]
62+
navigation = [
63+
("/software_factory", "active"),
64+
("/software_factory/history", "history"),
65+
("/software_factory/projects", "projects"),
66+
]
6367

6468
class Settings(AppSettings):
6569
tracker: Literal["none", "linear", "jira"] = Field(
@@ -143,44 +147,44 @@ async def get_tracker(cls, source: str | None = None) -> Tracker | None:
143147
# them. The attribute name is each agent's id (its durable settings/timeline key).
144148
generate_plan = Agent(
145149
description="ticket → implementation plan",
146-
prompt="ship/build/generate_plan.md",
150+
prompt="software_factory/build/generate_plan.md",
147151
contract=PlanOutput,
148152
model="codex",
149153
)
150154
review_plan = Agent(
151155
description="critiques the plan before any work starts",
152-
prompt="ship/build/review_plan.md",
156+
prompt="software_factory/build/review_plan.md",
153157
contract=ReviewOutput,
154158
model="claude",
155159
)
156160
revise_contract = Agent(
157161
description="revises the plan contract on feedback",
158-
prompt="ship/build/revise_contract.md",
162+
prompt="software_factory/build/revise_contract.md",
159163
contract=ContractRevisionOutput,
160164
model="codex",
161165
)
162166
implement = Agent(
163167
description="plan → diff, in a drukbox",
164-
prompt="ship/build/implement.md",
168+
prompt="software_factory/build/implement.md",
165169
contract=ImplementationOutput,
166170
model="claude",
167171
)
168172
evaluate_implementation = Agent(
169173
description="verification + code review of the diff, one verdict",
170-
prompt="ship/build/evaluate_implementation.md",
174+
prompt="software_factory/build/evaluate_implementation.md",
171175
contract=EvaluationOutput,
172176
model="codex",
173177
effort="medium",
174178
)
175179
triage_human_feedback = Agent(
176180
description="routes a human's PR feedback back into the workflow",
177-
prompt="ship/build/triage_human_feedback.md",
181+
prompt="software_factory/build/triage_human_feedback.md",
178182
contract=TriageOutput,
179183
model="codex",
180184
)
181185
repo_profiler = Agent(
182186
description="reads a repo once and reports its stack, verification commands, and skills",
183-
prompt="ship/profile/repo_profiler.md",
187+
prompt="software_factory/profile/repo_profiler.md",
184188
contract=RepoProfilerOutput,
185189
model="codex",
186190
)

0 commit comments

Comments
 (0)