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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

## Unreleased

### Add kotlin-sdk as first external fork-mode repo (ci-ofvhg)

Add modelcontextprotocol/kotlin-sdk as a repo in cistern.yaml with `delivery_mode: fork`, `upstream_remote: https://github.com/modelcontextprotocol/kotlin-sdk`, and `fork: https://github.com/MichielDean/kotlin-sdk`. Uses 1 cataractae (sufficient for samples/docs contributions). Also promotes the fork-mode aqueduct from a commented-out template in `aqueduct.yaml` to a standalone `aqueduct/feature-fork.yaml` workflow file, and adds the `feature-fork` aqueduct definition to the embedded `cistern.yaml` config.

**Key changes:**
- New `aqueduct/feature-fork.yaml` — standalone aqueduct definition for fork-mode repos (previously commented-out in aqueduct.yaml)
- `cmd/ct/assets/cistern.yaml` — added `feature-fork` aqueduct definition and `kotlin-sdk` repo entry with `delivery_mode: fork`
- `aqueduct/aqueduct.yaml` — removed commented-out fork-mode template (moved to standalone file)
- `cmd/ct/doctor_test.go` — generalized doctor test to iterate all aqueducts instead of only `default`
- `internal/aqueduct/workflow_test.go` — new test validating kotlin-sdk repo config parses in fork mode (all 6 fields)

### Inject external repo contributing guidelines as cataractae context (ci-agrc5)

For fork-mode repos, Cistern now automatically extracts contributing guidelines from the upstream repository and injects them into CONTEXT.md for all cataractae. This ensures that agents working on external repos follow the upstream project's own conventions (coding style, test commands, commit message format, etc.) instead of Cistern defaults when they conflict.
Expand Down
104 changes: 1 addition & 103 deletions aqueduct/aqueduct.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -94,106 +94,4 @@ cataractae:
timeout_minutes: 60
on_pass: done
on_recirculate: implement
on_pool: pooled

# Fork-mode variant: for external repos where you push to a fork and open a PR
# against upstream instead of merging directly. Use this workflow with a repo
# config that sets delivery_mode: fork and upstream_remote: <upstream-url>.
#
# name: feature-fork
#
# cataractae:
# - name: architect
# type: agent
# identity: architect
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-git
# - name: cistern-diff-reader
# timeout_minutes: 20
# on_pass: implement
# on_recirculate: architect
# on_fail: pooled
# on_pool: pooled
#
# - name: implement
# type: agent
# identity: implementer
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-git
# - name: cistern-test-runner
# timeout_minutes: 30
# on_pass: review
# on_fail: pooled
# on_pool: pooled
#
# - name: review
# type: agent
# identity: reviewer
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-git
# - name: cistern-diff-reader
# timeout_minutes: 20
# on_pass: qa
# on_fail: implement
# on_recirculate: implement
# on_pool: pooled
#
# - name: qa
# type: agent
# identity: qa
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-git
# - name: cistern-test-runner
# - name: cistern-diff-reader
# timeout_minutes: 20
# on_pass: security-review
# on_fail: implement
# on_recirculate: implement
# on_pool: pooled
#
# - name: security-review
# type: agent
# identity: security
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-diff-reader
# timeout_minutes: 15
# on_pass: docs
# on_fail: implement
# on_recirculate: implement
# on_pool: pooled
#
# - name: docs
# type: agent
# identity: docs_writer
# context: full_codebase
# skills:
# - name: cistern-signaling
# - name: cistern-git
# - name: cistern-diff-reader
# timeout_minutes: 20
# on_pass: fork-delivery
# on_fail: implement
# on_recirculate: implement
# on_pool: pooled
#
# - name: fork-delivery
# type: agent
# identity: fork-delivery
# skills:
# - name: cistern-signaling
# - name: cistern-github
# - name: cistern-git
# timeout_minutes: 60
# on_pass: done
# on_recirculate: implement
# on_pool: pooled
on_pool: pooled
101 changes: 101 additions & 0 deletions aqueduct/feature-fork.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Fork-mode variant: for external repos where you push to a fork and open a PR
# against upstream instead of merging directly. Use this workflow with a repo
# config that sets delivery_mode: fork and upstream_remote: <upstream-url>.

name: feature-fork

cataractae:
- name: architect
type: agent
identity: architect
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: implement
on_recirculate: architect
on_fail: pooled
on_pool: pooled

- name: implement
type: agent
identity: implementer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-test-runner
timeout_minutes: 30
on_pass: review
on_fail: pooled
on_pool: pooled

- name: review
type: agent
identity: reviewer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: qa
on_fail: implement
on_recirculate: implement
on_pool: pooled

- name: qa
type: agent
identity: qa
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-test-runner
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: security-review
on_fail: implement
on_recirculate: implement
on_pool: pooled

- name: security-review
type: agent
identity: security
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-diff-reader
timeout_minutes: 15
on_pass: docs
on_fail: implement
on_recirculate: implement
on_pool: pooled

- name: docs
type: agent
identity: docs_writer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: fork-delivery
on_fail: implement
on_recirculate: implement
on_pool: pooled

- name: fork-delivery
type: agent
identity: fork-delivery
skills:
- name: cistern-signaling
- name: cistern-github
- name: cistern-git
timeout_minutes: 60
on_pass: done
on_recirculate: implement
on_pool: pooled
101 changes: 101 additions & 0 deletions cmd/ct/assets/cistern.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,99 @@ aqueducts:
type: automated
on_pass: done

# Fork-mode variant: for external repos where you push to a fork and open a PR
# against upstream instead of merging directly.
- name: feature-fork
cataractae:
- name: architect
type: agent
identity: architect
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: implement
on_recirculate: architect
on_fail: pooled
on_pool: pooled
- name: implement
type: agent
identity: implementer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-test-runner
timeout_minutes: 30
on_pass: review
on_fail: pooled
on_pool: pooled
- name: review
type: agent
identity: reviewer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: qa
on_fail: implement
on_recirculate: implement
on_pool: pooled
- name: qa
type: agent
identity: qa
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-test-runner
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: security-review
on_fail: implement
on_recirculate: implement
on_pool: pooled
- name: security-review
type: agent
identity: security
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-diff-reader
timeout_minutes: 15
on_pass: docs
on_fail: implement
on_recirculate: implement
on_pool: pooled
- name: docs
type: agent
identity: docs_writer
context: full_codebase
skills:
- name: cistern-signaling
- name: cistern-git
- name: cistern-diff-reader
timeout_minutes: 20
on_pass: fork-delivery
on_fail: implement
on_recirculate: implement
on_pool: pooled
- name: fork-delivery
type: agent
identity: fork-delivery
skills:
- name: cistern-signaling
- name: cistern-github
- name: cistern-git
timeout_minutes: 60
on_pass: done
on_recirculate: implement
on_pool: pooled

repos:
- name: ScaledTest
url: https://github.com/example/ScaledTest
Expand All @@ -39,6 +132,14 @@ repos:
- marcia
prefix: ct

- name: kotlin-sdk
url: https://github.com/MichielDean/kotlin-sdk
aqueduct: feature-fork
cataractae: 1
prefix: ks
delivery_mode: fork
upstream_remote: https://github.com/modelcontextprotocol/kotlin-sdk

handoff_token_threshold: 100000

# heartbeat_interval controls how often the Castellarius scans for orphaned or
Expand Down
23 changes: 13 additions & 10 deletions cmd/ct/doctor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2201,16 +2201,19 @@ func TestRunDoctorExtendedChecks_DefaultWorkflow_InstallerStubs_Passes(t *testin
}

// Generate AGENTS.md files for all identities, mirroring what ct init does.
w, err := cfg.ResolveAqueduct("default")
if err != nil {
t.Fatalf("resolve aqueduct: %v", err)
}
if err := initCataractaeDir(w, cataractaeDir); err != nil {
t.Fatalf("init cataractae dir: %v", err)
}
preset, _ := cfg.ResolveProvider("")
if _, err := aqueduct.GenerateCataractaeFiles(w, cataractaeDir, preset.InstrFile()); err != nil {
t.Fatalf("generate AGENTS.md files: %v", err)
// Must cover every aqueduct defined in the config since doctor checks all repos.
for _, aquedef := range cfg.Aqueducts {
w, err := cfg.ResolveAqueduct(aquedef.Name)
if err != nil {
t.Fatalf("resolve aqueduct %s: %v", aquedef.Name, err)
}
if err := initCataractaeDir(w, cataractaeDir); err != nil {
t.Fatalf("init cataractae dir for %s: %v", aquedef.Name, err)
}
preset, _ := cfg.ResolveProvider("")
if _, err := aqueduct.GenerateCataractaeFiles(w, cataractaeDir, preset.InstrFile()); err != nil {
t.Fatalf("generate AGENTS.md files for %s: %v", aquedef.Name, err)
}
}

// installerStubs mirrors _install_skill_stubs in tests/installer/run-tests.sh.
Expand Down
Loading