Set coilyco ward workflow defaults in the aos KDL bundle #345
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/agentic-os#345
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Goal
Update the aos-authored ward KDL bundle so the coilyco deployment keeps direct-main as its fleet default while ward itself opts back into PR workflow.
This is the deployment-config slice for the ward workflow transition. It depends on ward supporting workflow policy in
smart-defaultsKDL (ward#707) and on PR workflow being able to complete the PR, CI, review, and merge lifecycle (ward#706).Context
Aos is the source of truth for the coilyco ward spec bundle under
.ward/, perdocs/ward-specs.md. Ward consumes this bundle at release time. The requested shape is:Desired config
Once ward#707 lands a schema, update
.ward/ward-kdl.defaults.kdlwith the equivalent of:Keep the exact syntax aligned with the schema that lands in ward#707.
Acceptance
direct-main.coilyco-flight-deck/wardresolves topr.pre-commit run --all-filesor the repo'sward execvalidation passes.🔎 ward agent advisor
ward agent advisor --harness gooseran a one-shot standard research pass on this question:pre-commit installed at .git/hooks/pre-commit
pre-commit installed at .git/hooks/commit-msg
wrote /home/ubuntu/.mcporter/mcporter.json
____) 20260708_1 · /workspace/agentic-os
L L goose is ready
────────────────────────────────────────
▸ list_resources extensionmanager
────────────────────────────────────────
▸ load_skill
name: tooling-warp
────────────────────────────────────────
▸ analyze
path: .ward
────────────────────────────────────────
▸ shell
command: find . -name "*.kdl" -type f | head -10
────────────────────────────────────────
▸ shell
command: ls -la .ward/
0 files, 0L, 0F, 0C (depth=3)
(8 files skipped: no parser)
./.ward/ward-kdl.forgejo.guardfile.kdl
./.ward/ward-kdl.signoz.guardfile.kdl
./.ward/ward-kdl.fleet.kdl
./.ward/ward-kdl.ollama.guardfile.kdltotal 328
dr-xr-xr-x 2 ubuntu ubuntu 4096 Jul 8 22:19 .
dr-xr-xr-x 19 ubuntu ubuntu 4096 Jul 8 22:19 ..
-r--r--r-- 1 ubuntu ubuntu 139714 Jul 8 22:19 forgejo.swagger.lock.json
-r--r--r-- 1 ubuntu ubuntu 118003 Jul 8 22:19 glitchtip.openapi.lock.json
-r--r--r-- 1 ubuntu ubuntu 16703 Jul 8 22:19 signoz.openapi.lock.json
-r--r--r-- 1 ubuntu ubuntu 1961 Jul 8 22:19 ward-kdl.fleet.kdl
-r--r--r-- 1 ubuntu ubuntu 15500 Jul 8 22:19 ward-kdl.forgejo.guardfile.kdl
-r--r--r-- 1 ubuntu ubuntu 1762 Jul 8 22:19 ward-kdl.ollama.guardfile.kdl
-r--r--r-- 1 ubuntu ubuntu 4863 Jul 8 22:19 ward-kdl.signoz.guardfile.kdl
-r--r--r-- 1 ubuntu ubuntu 11292 Jul 8 22:19 ward.yaml
────────────────────────────────────────
▸ shell
command: grep -r "smart-defaults" .ward/ || echo "No smart-defaults found"
No smart-defaults found
────────────────────────────────────────
▸ shell
command: cat .ward/ward-kdl.fleet.kdl
fleet {
schema-version 2
}
────────────────────────────────────────
▸ shell
command: cat .ward/ward-kdl.defaults.kdl 2>/dev/null || echo "File does not exist"
File does not exist
────────────────────────────────────────
▸ search_available_extensions extensionmanager
────────────────────────────────────────
▸ shell
command: find /substrate -name "ward" -type d | head -10
/substrate/lore/.ward
/substrate/deploy/.ward
/substrate/ward
/substrate/ward/examples/toy/.ward
/substrate/ward/examples/ward-specs
/substrate/ward/.ward
/substrate/ward/.ward/ward-kdl
/substrate/ward/.ward/ward-kdl/ward-kdl-admin
/substrate/ward/.ward/ward-kdl/ward-kdl-read
/substrate/ward/.ward/ward-kdl/ward-kdl-write
────────────────────────────────────────
▸ shell
command: ls -la /substrate/ward/.ward/ward-kdl/
total 1332
drwxr-xr-x 5 root root 4096 Jul 8 22:19 .
drwxr-xr-x 3 root root 4096 Jul 8 22:19 ..
-rw-r--r-- 1 root root 119 Jul 8 22:19 README.md
-rw-r--r-- 1 root root 139714 Jul 8 22:19 forgejo.swagger.lock.json
-rw-r--r-- 1 root root 4632 Jul 8 22:19 glama.openapi.json
-rw-r--r-- 1 root root 6005 Jul 8 22:19 glama.openapi.lock.json
-rw-r--r-- 1 root root 247713 Jul 8 22:19 glitchtip.openapi.json
-rw-r--r-- 1 root root 118003 Jul 8 22:19 glitchtip.openapi.lock.json
-rw-r--r-- 1 root root 12853 Jul 8 22:19 signoz.openapi.json
-rw-r--r-- 1 root root 16703 Jul 8 22:19 signoz.openapi.lock.json
-rw-r--r-- 1 root root 2783 Jul 8 22:19 skillsmp.openapi.json
-rw-r--r-- 1 root root 2983 Jul 8 22:19 skillsmp.openapi.lock.json
-rw-r--r-- 1 root root 13189 Jul 8 22:19 specverb.lock
-rw-r--r-- 1 root root 60203 Jul 8 22:19 tailscale.openapi.lock.json
-rw-r--r-- 1 root root 225855 Jul 8 22:19 tailscale.openapi.yaml
-rw-r--r-- 1 root root 258619 Jul 8 22:19 trello.openapi.json
-rw-r--r-- 1 root root 71203 Jul 8 22:19 trello.openapi.lock.json
drwxr-xr-x 2 root root 4096 Jul 8 22:19 ward-kdl-admin
drwxr-xr-x 2 root root 4096 Jul 8 22:19 ward-kdl-read
drwxr-xr-x 2 root root 4096 Jul 8 22:19 ward-kdl-write
-rw-r--r-- 1 root root 942 Jul 8 22:19 ward-kdl.aider.guardfile.kdl
-rw-r--r-- 1 root root 1597 Jul 8 22:19 ward-kdl.aws.guardfile.kdl
-rw-r--r-- 1 root root 4097 Jul 8 22:19 ward-kdl.brew.guardfile.kdl
-rw-r--r-- 1 root root 1162 Jul 8 22:19 ward-kdl.claude.guardfile.kdl
-rw-r--r-- 1 root root 1145 Jul 8 22:19 ward-kdl.codex.guardfile.kdl
-rw-r--r-- 1 root root 464 Jul 8 22:19 ward-kdl.defaults.kdl
-rw-r--r-- 1 root root 3609 Jul 8 22:19 ward-kdl.docker.guardfile.kdl
-rw-r--r-- 1 root root 3533 Jul 8 22:19 ward-kdl.eco-observe.guardfile.kdl
-rw-r--r-- 1 root root 4609 Jul 8 22:19 ward-kdl.fleet.kdl
-rw-r--r-- 1 root root 2481 Jul 8 22:19 ward-kdl.forgejo-key.guardfile.kdl
-rw-r--r-- 1 root root 15500 Jul 8 22:19 ward-kdl.forgejo.guardfile.kdl
-rw-r--r-- 1 root root 3738 Jul 8 22:19 ward-kdl.git.guardfile.kdl
-rw-r--r-- 1 root root 2275 Jul 8 22:19 ward-kdl.glama.guardfile.kdl
-rw-r--r-- 1 root root 6025 Jul 8 22:19 ward-kdl.glitchtip.guardfile.kdl
-rw-r--r-- 1 root root 949 Jul 8 22:19 ward-kdl.goose.guardfile.kdl
-rw-r--r-- 1 root root 3223 Jul 8 22:19 ward-kdl.kubectl.guardfile.kdl
-rw-r--r-- 1 root root 1762 Jul 8 22:19 ward-kdl.ollama.guardfile.kdl
-rw-r--r-- 1 root root 1172 Jul 8 22:19 ward-kdl.opencode.guardfile.kdl
-rw-r--r-- 1 root root 4863 Jul 8 22:19 ward-kdl.signoz.guardfile.kdl
-rw-r--r-- 1 root root 1918 Jul 8 22:19 ward-kdl.skillsmp.guardfile.kdl
-rw-r--r-- 1 root root 1825 Jul 8 22:19 ward-kdl.tailscale.guardfile.kdl
-rw-r--r-- 1 root root 290 Jul 8 22:19 ward-kdl.topology.kdl
-rw-r--r-- 1 root root 1908 Jul 8 22:19 ward-kdl.trello.guardfile.kdl
────────────────────────────────────────
▸ shell
command: cat /substrate/ward/.ward/ward-kdl/ward-kdl.defaults.kdl
smart-defaults {
agent-reservation-ttl "1h"
agent-reservation-recheck-max "15s"
agent-reap-idle "1h"
agent-reap-max-cpu "5.0"
director-max-parallel "10"
director-limit "50"
director-poll-interval "30s"
reviewer-timeout "8m"
config-bundle-ttl "600"
container-assets-ttl "1h"
container-read-only-extra-repo-ttl "24h"
container-reap-keep "10"
// TODO: move advisor depth budgets and container-research setup budget.
}
────────────────────────────────────────
▸ shell
command: grep -r "agent-workflow" /substrate/ward/.ward/ward-kdl/ || echo "No agent-workflow found"
No agent-workflow found
────────────────────────────────────────
▸ shell
command: cat /substrate/ward/.ward/ward-kdl/ward-kdl.fleet.kdl
// Fleet config for ward (cli-guard fleetconfig, DIALECT 2). This is NOT a
// guardfile: it names which agents the ward fleet can run and how each one is
// launched (binary, context level, argv shape, model), never a permission. The
//
.fleet.kdlsuffix - no.guardfile.infix - keeps it out of the ward-kdl// guardfile auto-discovery glob (ward-kdl..guardfile.kdl) and the exec/ops
// mirrors; it rides its own embed dir (cmd/ward/fleetassets/) and parser
// (cmd/ward/fleet.go via pkg/fleetconfig), legibly partitioned from the
// permission dialect (aos#310 §6, ward#415).
//
// This file is the single hand-edited source.
make sync-fleet-assetscopies// it to cmd/ward/fleetassets/fleet.generated.kdl for go:embed (which cannot
// reach this sibling dir); fleetassets_test.go fails the build on drift.
//
// This is the single source of the roster + per-agent divergence, feeding the
// container_bootstrap.go env-defaults, restated in the ratified fleet grammar.
// ward#419 deleted the old agent-adapters.yaml mirror, collapsing the ward#415
// three-way pin to a two-way one: the contract test (agent_adapter_test.go,
// TestFleetSwitchesTwoWayPin) pins fleet.generated.kdl <-> the parseMode roster.
//
// POST-#412 roster:
opencodeis the canonical harness key (qwen is only the// backing model + a deprecated --mode alias). The runtime reads this manifest
// (bootstrap defaults + the launcher-facing projection in agent_adapter.go).
fleet {
schema-version 2
// defaults mirror the container_bootstrap.go env-default constants: WARD_MODE
// -> defaults.agent, WARD_GIT_NAME/WARD_GIT_EMAIL -> defaults.attribution.
defaults {
agent claude
attribution name=coilyco-ops email=coilyco-ops@coilysiren.me
}
// claude: full context (2), stream-json headless, keychain auth. model /
// reasoning-effort are override-only (ward#616): empty defaults keep bare launch.
agent claude {
binary claude
context-level 2
stream stream-json
auth claude-keychain
model ""
reasoning-effort ""
argv {
preflight claude -p
headless claude -p --verbose --output-format stream-json
interactive claude
}
}
// codex: scoped context (level 1), no stream, codex-file auth, no pre-flight.
agent codex {
binary codex
context-level 1
stream none
auth codex-file
model gpt-5.4
reasoning-effort medium
verbosity low
argv {
headless codex exec
interactive codex
}
}
// opencode: minimal context (level 0), no stream, no host auth, no pre-flight.
agent opencode {
binary opencode
context-level 0
stream none
auth none
model qwen3-coder:30b
endpoint "http://localhost:11434/v1"
argv {
headless opencode run
interactive opencode
}
}
// goose: full context (level 2) like claude, no stream, ollama auth.
agent goose {
binary goose
context-level 2
stream none
auth ollama
argv {
preflight goose run -t
headless goose run -t
interactive goose session
}
}
// Per-role capability roster (ward#578) + per-agent model/effort overlay
// (cli-guard#192, ward#620); overlay precedence in docs/agent-config-overrides.md.
roles {
// engineer: no host reach; a cheaper model for parallel fan-out (ward#620).
role engineer {
agent claude {
model claude-fable-5
reasoning-effort medium
}
agent codex {
model gpt-5.4-mini
reasoning-effort medium
}
}
// director mirrors advisor's live-observe set (aws + tailnet, ward#547); its
// heartbeat wants the strongest model at 1M context (ward#620).
role director {
guardfiles ward-kdl.aws.guardfile.kdl ward-kdl.tailscale.guardfile.kdl
agent claude {
model "claude-opus-4-8[1m]"
reasoning-effort high
}
agent codex {
model gpt-5.5
reasoning-effort medium
}
}
// advisor does live-observe research: the aws SSM read + the tailnet route.
//
advisor --no-tailnetopts a rare isolated run back out.role advisor {
guardfiles ward-kdl.aws.guardfile.kdl ward-kdl.tailscale.guardfile.kdl
}
}
}
────────────────────────────────────────
▸ shell
command: find /substrate/ward -name ".md" -exec grep -l "smart-defaults|workflow.*policy" {} ;
/substrate/ward/README.md
/substrate/ward/docs/troubleshooting.md
/substrate/ward/docs/agent-workflow.md
/substrate/ward/docs/agent-director-dispatch.md
/substrate/ward/docs/FEATURES.md
/substrate/ward/docs/agent-reservation.md
/substrate/ward/docs/config-source.md
/substrate/ward/docs/container-cleanup.md
/substrate/ward/docs/agent-reserved-immutable.md
/substrate/ward/docs/agent.md
────────────────────────────────────────
▸ shell
command: cat /substrate/ward/docs/agent-workflow.md
doc_goal: Let an operator pick the right per-run landing policy - direct-main, pr, or patch-only - by trust level and understand exactly what each mode changes in the seed, container env/label, and reaper gate, including the honest first-slice limits like the still-push-capable token.
ward agent: workflow modes
--workflowpicks a dispatched engineer's landing policy - how the run isallowed to turn finished work into a landed change (ward#508). One run, one
container, one issue; the workflow decides only how it lands, not what it
builds.
The default is
direct-main, so an unflagged run behaves exactly as it alwayshas. The mode is visible in
--printoutput, rides the container as theWARD_WORKFLOWenv var and award.workflowlabel, and is read by the reaper.The three modes
direct-main(default) - the fast path: implement, commit, merge tomain, push, and close the issue with acloses #Ntrailer. Intended for solorepos, trusted automation, and low-review surfaces. On GitHub (whose
mainis typically protected)
direct-mainalready lands via a pull request - theforge decides, so the two collapse there.
pr- carry the work to a branch and a pull request instead of landingon
maindirectly. The PR is the merge gate; a human or a follow-up loop landsit. The seed tells the agent to push the branch and open the PR, and not to
push
main.patch-only- the run has no landing authority: it commits locally butproduces a patch (
git format-patch origin/main --stdout) and posts it in acomment for a human to review and apply. It neither pushes
mainnor opens aPR, and writes no
closes #Ntrailer. Intended for untrusted targets,experiments, and high-risk work.
Which mode for which trust level
direct-main.pr.before it touches the tree) -
patch-only.What the mode actually changes
retrospective's "only after ..." landing phrase both shift with the mode, so a
patch-onlyrun is never told to merge tomain, and aprrun is never toldto push it. See agent.md for the seed shape.
WARD_WORKFLOW=<mode>andwears a
ward.workflow=<mode>label;direct-mainomits both.ward container reapnormally force-lands residual work onmainat teardown. For apr/patch-onlyrun it readsWARD_WORKFLOWandrefuses to push
main, preserving any residual work on award-salvage/<id>branch instead. See container-reap.md.
Rough edges (first slice)
This first slice is deliberately minimal:
patch-onlyis enforced at the prompt + reaper layer, not the credentiallayer: the container still carries a push-capable token. Hard credential scoping
(a read-only token) is the deferred "read-only credential hardening".
pr/patch-onlyrun's residual local commits are preserved on a salvagebranch by the reaper (safe, but noisier than a dedicated "held" outcome).
terms; it judges feasibility, not the landing contract, so it is left as-is.
See also
ward agentverb family and the seed prompt.direct-mainalready lands via a PR.────────────────────────────────────────
▸ shell
command: cat /substrate/ward/docs/config-source.md
doc_goal: Pin the WARD_CONFIG_REF config-source seam - the fs.FS the KDL build sites compile from, the unset-means-baked selection contract, the flat bundle layout, and the per-site degrade behavior.
The config source:
WARD_CONFIG_REFand the fs.FS-at-launch seamSince ward#653 (epic ward#650), ward's KDL surfaces compile at launch from a selected
fs.FS, not a hard-wired embed.cmd/ward/configsource.gopicks it. Four sites read it:ward ops forgejo- spec guardfile + swagger lock, plus the optional admin guardfile.ward docker,ward agents <tool>,ward ops {aws,kubectl,...}.fleetconfig.Parse.cmd/ward/smartdefaults.go.Selection contract
.ward/ward-kdl/(drift-tested).file://<dir>-os.DirFS(<dir>)over a local bundle directory in theflat layout below.
<host>/<owner>/<repo>[@<ref>]//<subpath>- the git-ref grammar, synced through the TTL-cached resolver (config-ref-resolver.md).Bundle layout
A ref points at a flat bundle directory - the aos#332 layout, same as
.ward/ward-kdl/:ward-kdl.forgejo.guardfile.kdl+forgejo.swagger.lock.json- the specsurface for
ops forgejo.ward-kdl.<area>.guardfile.kdl(exec dialect) - auto-mounted at theirwrappath (ward-kdl-in-ward.md); the exec scan mounts only
files carrying an
execblock.ward-kdl.fleet.kdl- the dialect-2 fleet manifest.ward-kdl.defaults.kdl- the launch-selected smart defaults for runtime policy knobs like reservation TTL, director cadence, and container retention.ward-kdl.topology.kdl- container topology overlay. Env wins.forgejo-admin.guardfile.kdl- optional; omitting it withholdsops forgejo admin/doctor.Failure behavior
A set-but-unresolvable ref and a bundle that fails to parse both degrade per site, loudly:
ward ops forgejomounts the error leaf - the failure surfaces oninvocation (
guardfile runtime failed to mount: ...), so a bad bundle cannever silently drop a verb surface.
ward agents list,ward agent ...) error at verb time.ward agent reap,ward agent director,ward agent review, reservation/comment code paths, container cleanup) error atverb time.
version,exec,git, ...) keeps working.There is no fallback from a named-but-broken source to the baked default.
See also
────────────────────────────────────────
▸ shell
command: ls -la /substrate/ward/docs/ | grep -E "(smart|default)"
(no output)
Command exited with code 1
────────────────────────────────────────
▸ shell
command: find /substrate/ward -name "*.md" -exec grep -l "smart-defaults|ward-kdl.defaults.kdl" {} ;
/substrate/ward/docs/troubleshooting.md
/substrate/ward/docs/ward-kdl.md
/substrate/ward/docs/agent-director-dispatch.md
/substrate/ward/docs/FEATURES.md
/substrate/ward/docs/agent-reservation.md
/substrate/ward/docs/config-source.md
/substrate/ward/docs/container-cleanup.md
/substrate/ward/docs/agent-reserved-immutable.md
────────────────────────────────────────
▸ shell
command: cat /substrate/ward/docs/ward-kdl.md | head -50
doc_goal: One answer to what ward-kdl is, how it differs from ward, and whether a repo needs a guardfile - build-time authoring layer vs run-time product.
ward-kdl: the build-time authoring layer
ward-kdl is the build-time authoring layer.
wardis the run-time product that embeds what it authors. cli-guard is the engine both stand on. Three roles, told apart by when they run. The conceptual model lives in architecture.md.Do you need to author a guardfile? (start here)
Almost certainly not. A repo needs a guardfile only when it runs its own
ward opsoperator surface. Dev-verb adoption is.ward/ward.yamland nothing else.The fork every adopter hits first:
ward exec build/test/lint,ward git, the audit log) on your repo: a committed.ward/ward.yamlis the whole contract, no guardfile. That surface is forge-agnostic and already embedded in the installedward. See ward-yaml.md.ward ops forgejo/aws, the fleet roster) against your own endpoints, tokens, and owner gate: only then a guardfile, and even then you swap placeholders in the neutral example bundle and rebuild from source. See ward-kdl-authoring.md and the grammar in guardfile-grammar.md. Guardfiles are ward's own build-time internals, not a per-repo file award execuser maintains.Build time: source in, validated artifact out
You author a source file, cli-guard compiles or validates it,
wardembeds theresult. Nothing is fetched at runtime.
ward-kdlisprotocfor permissions andfleet config, and you rarely run it by hand: you run what it produced and
regenerate when the source changes (
make build-ward-kdl). Three dialects:*.guardfile.kdlspec + exec files. Least-privilege, audited. Parsed bycli/execverb+http/specverb.ward-kdl.fleet.kdl: identity, model, endpoint, attribution, roster defaults, sparse overrides,roles.fleetconfigparser, sourced from a local~/.ward/fleet.local.kdl, not embedded and tracked separately.ward-kdl.defaults.kdl: launch-selected runtime policy defaults for reservation TTL, recheck cadence, reap thresholds, director cadence, and container retention. Parsed by ward at launch, embedded viadefaultsassets/.Run time:
wardembeds the emitted surfacesward(public facewarded) is the product a user installs. It embeds the ward-kdl surfaces asward ops <api>,ward docker,ward agents <target>, then adds the run-time-only layers ward-kdl never produces:ward agentandward exec. The embeds are the baked default:WARD_CONFIG_REFcan select a live bundle at launch (config-source.md). Exec guardfiles auto-mount at theirwrappath (ward-kdl-in-ward.md).The per-area reference docs
Every guardfile gets a generated reference doc beside it, committed under docs/ward-kdl/. Emitted by ward-kdl's
surface.Markdown(), they describe one area's verbs. ward-kdl-surface.md is the flat index across every area.See also
ward.Cross-reference convention from coilysiren/agentic-os#59.
────────────────────────────────────────
▸ shell
command: grep -A 20 -B 5 "agent-workflow" /substrate/ward/docs/troubleshooting.md
(no output)
Command exited with code 1
────────────────────────────────────────
▸ shell
command: grep -r "agent-workflow" /substrate/ward/docs/
/substrate/ward/docs/FEATURES.md:-
--workflow direct-main|pr|patch-only(ward#508) - the dispatched engineer's landing policy:direct-main(default) merges tomainand closes (unchanged);propens a branch + pull request;patch-onlyposts a patch with no landing authority. The mode shifts the seed, rides the container env + award.workflowlabel, and gates the reaper'smainpush. See agent-workflow.md./substrate/ward/docs/agent.md:- agent-workflow.md -
--workflow direct-main|pr|patch-only, the run's landing policy.────────────────────────────────────────
▸ todo_write todo
content: - [x] Analyze current KDL structures in agentic-os and ward repos
Identify existing workflow configuration patterns
Research smart-defaults schema from ward#707 (not yet implemented)
Determine where to add the agent-workflow configuration
Review issue requirements for the coilyco override
Gather context on PR workflow dependencies: ward#706 and ward#707
────────────────────────────────────────
▸ shell
command: curl -s "https://forgejo.coilysiren.me/api/v1/repos/coilyco-flight-deck/ward/issues/707" | grep -E ""title":"|"body":""
{"id":4200,"url":"https://forgejo.coilysiren.me/api/v1/repos/coilyco-flight-deck/ward/issues/707","html_url":"coilyco-flight-deck/ward#707","number":707,"user":{"id":7,"login":"coilyco-ops","login_name":"","source_id":0,"full_name":"Coilyco Robotic Operations Division","email":"coilyco-ops@noreply.forgejo.coilysiren.me","avatar_url":"https://forgejo.coilysiren.me/avatars/ed264a3b7b6770327da211496912cfff5bacae8ac8fa8a9748e3d5ea638b875e","html_url":"https://forgejo.coilysiren.me/coilyco-ops","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-06-18T03:44:21Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"ro / bot","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"coilyco-ops"},"original_author":"","original_author_id":0,"title":"Make agent workflow defaults configurable and default engineers to PRs","body":"## Goal\n\nMake ward's agent workflow selection config-driven, flip warded engineers to PR workflow by default, and support per-repo workflow overrides.\n\nThis is the configuration half of the direct-main to PR transition. It should land after or alongside the PR lifecycle work in ward#706, because defaulting to
prshould mean the run can actually create the PR, wait for CI, and merge with a merge commit.\n\n## Current behavior\n\n*cmd/ward/agent_workflow.gohasdefaultWorkflow = workflowDirectMain.\n*workflowFlag()exposes--workflowwith a hard-codeddirect-maindefault.\n*agentWorkflow()only parses the CLI flag.\n*container_compute.goomitsWARD_WORKFLOWand theward.workflowlabel for default/direct-main runs.\n*docs/agent-workflow.mddocuments direct-main as the default.\n* Runtime policy KDL currently lives inward-kdl.defaults.kdlundersmart-defaults, but it has no workflow policy nodes.\n\n## Desired behavior\n\n* The built-in ward default becomespr.\n*smart-defaultsKDL can set the default workflow.\n*smart-defaultsKDL can override workflow by repo, keyed by owner/repo.\n* CLI--workflowstill wins over config.\n* Repo override wins over fleet/default workflow.\n* Invalid configured workflow values fail closed with a useful error.\n* Dry-run/print output, reservation records, container env/labels, seed prompts, docs, and tests all show the resolved workflow.\n* Existing explicit--workflow direct-mainand--workflow patch-onlybehavior keeps working.\n\n## Sketch\n\nOne plausible KDL shape:\n\nkdl\nsmart-defaults {\n agent-workflow default=\"pr\" {\n repo \"coilyco-flight-deck/agentic-os\" workflow=\"direct-main\"\n repo \"coilyco-flight-deck/ward\" workflow=\"pr\"\n }\n}\n\n\nUse the repo key that is already resolved by dispatch (agentIssueRef.repoSlug()), not cwd discovery, so bare refs and full refs behave the same.\n\n## Acceptance\n\n* Unit tests cover built-in default, KDL default, repo override, CLI precedence, invalid values, and env/label projection.\n*docs/agent-workflow.mdis updated to describe PR as the default and config override precedence.\n*docs/FEATURES.mdis updated if this changes the feature inventory.","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":1,"created_at":"2026-07-08T22:12:40Z","updated_at":"2026-07-08T22:19:00Z","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":4,"name":"ward","owner":"coilyco-flight-deck","full_name":"coilyco-flight-deck/ward"},"pin_order":0}────────────────────────────────────────
▸ shell
command: curl -s "https://forgejo.coilysiren.me/api/v1/repos/coilyco-flight-deck/ward/issues/706" | grep -E ""title":"|"body":""
{"id":4199,"url":"https://forgejo.coilysiren.me/api/v1/repos/coilyco-flight-deck/ward/issues/706","html_url":"coilyco-flight-deck/ward#706","number":706,"user":{"id":7,"login":"coilyco-ops","login_name":"","source_id":0,"full_name":"Coilyco Robotic Operations Division","email":"coilyco-ops@noreply.forgejo.coilysiren.me","avatar_url":"https://forgejo.coilysiren.me/avatars/ed264a3b7b6770327da211496912cfff5bacae8ac8fa8a9748e3d5ea638b875e","html_url":"https://forgejo.coilysiren.me/coilyco-ops","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2026-06-18T03:44:21Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"ro / bot","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"coilyco-ops"},"original_author":"","original_author_id":0,"title":"Make PR workflow create, wait, and merge pull requests","body":"## Goal\n\nChange
--workflow prfrom a branch-and-human-gate prompt into a complete ward landing workflow for Forgejo engineers.\n\nToday PR workflow only tells the container agent to push a branch and open a pull request, then it stops. The requested default change needs PR mode to be a real autonomous path first: create the PR, wait for Forgejo Actions or required status checks to finish, run the existing review gate after CI is green, then merge the PR with a merge commit.\n\n## Context read before filing\n\n*cmd/ward/agent_workflow.gocurrently documentspras branch + PR with a human or follow-up loop landing it.\n*docs/agent-workflow.mdsays the same and names this as a first-slice limitation.\n*docs/ward-kdl/ward-kdl.forgejo.write.guardfile.mdcurrently denies PR view/list and says PRs are read through the web UI.\n* The Forgejo swagger lock already contains pull request, action task, branch protection, and merge related shapes, so this is a product/guarded-surface gap rather than an API absence.\n\n## Desired behavior\n\n* Forgejoprworkflow opens a real pull request againstmainfrom the feature branch.\n* Ward waits for CI/status checks for that PR branch/head before review and merge.\n* Ward runs the existing in-container review gate only after CI is green.\n* Ward merges with a merge commit, not squash, rebase, or fast-forward.\n* The issue close path is preserved through the PR body or merge commit message usingcloses #N.\n* Failure to create the PR, green CI, pass review, or merge is reported as blocked/failed with useful context on the issue.\n* GitHub behavior stays compatible with the existing GitHub PR lane.\n\n## Notes\n\nThis should not rely on the agent improvising hiddencurlcalls. Prefer a ward-owned helper or guarded Forgejo verbs with tests around request shape, polling behavior, and failure classification.","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":1,"created_at":"2026-07-08T22:12:26Z","updated_at":"2026-07-08T22:13:05Z","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":4,"name":"ward","owner":"coilyco-flight-deck","full_name":"coilyco-flight-deck/ward"},"pin_order":0}{"summary":"## Summary\n\nThis issue is about updating the aos-authored ward KDL bundle to override the default workflow for the coilyco deployment while keeping ward itself configured to use PR workflow by default. Based on the context and the referenced issues (ward#706 and ward#707), I've analyzed the configuration structure required.\n\n## Analysis\n\nFrom my research, I identified that:\n\n1. Current State: Theward-kdl.defaults.kdlfile inwardrepo currently contains only basic smart-defaults configuration but lacks workflow configuration capabilities\n2. Required Changes: Once ward#707 (smart-defaults schema for workflow) lands, the agentic-os KDL bundle needs to be updated to set agent-workflow default as "direct-main" while specifically overriding the coilyco-flight-deck/ward repo to use "pr"\n3. Configuration Location: The aos bundle should modify.ward/ward-kdl.defaults.kdl(or equivalent) to add the workflow configuration\n4. Schema: Based on the ward#707 issue description, the expected KDL shape is:\nkdl\nsmart-defaults {\n agent-workflow default=\"direct-main\" {\n repo \"coilyco-flight-deck/ward\" workflow=\"pr\"\n }\n}\n\n\n## Risk Assessment\n\n- Dependency Risk: This change is dependent on ward#707 landing first to implement the smart-defaults schema for agent-workflow configuration. Without this, the configuration will not parse correctly.\n- Compatibility Risk: The PR workflow lifecycle (ward#706) must be fully implemented so that coilyco-flight-deck/ward can successfully go through full PR creation, CI wait, review, and merge lifecycle.\n- Timing Risk: If agentic-os makes changes before ward#707 is implemented, the KDL will fail to parse during ward's startup.\n\n## Recommendation\n\nThis should be implemented AFTER ward#707 lands with implementation of the smart-defaults schema for agent workflow. The change should be limited to modifying the.ward/ward-kdl.defaults.kdlfile inside the agentic-os repository, with validation that it parses correctly usingpre-commit run --all-filesorward execas specified in the issue acceptance criteria.", "issues": [{"repo": "coilyco-flight-deck/ward", "title": "Make agent workflow defaults configurable and default engineers to PRs", "body": "## Goal\n\nMake ward's agent workflow selection config-driven, flip warded engineers to PR workflow by default, and support per-repo workflow overrides.\n\nThis is the configuration half of the direct-main to PR transition. It should land after or alongside the PR lifecycle work in ward#706, because defaulting toprshould mean the run can actually create the PR, wait for CI, and merge with a merge commit.\n\n## Current behavior\n\n*cmd/ward/agent_workflow.gohasdefaultWorkflow = workflowDirectMain.\n*workflowFlag()exposes--workflowwith a hard-codeddirect-maindefault.\n*agentWorkflow()only parses the CLI flag.\n*container_compute.goomitsWARD_WORKFLOWand theward.workflowlabel for default/direct-main runs.\n*docs/agent-workflow.mddocuments direct-main as the default.\n* Runtime policy KDL currently lives inward-kdl.defaults.kdlundersmart-defaults, but it has no workflow policy nodes.\n\n## Desired behavior\n\n* The built-in ward default becomespr.\n*smart-defaultsKDL can set the default workflow.\n*smart-defaultsKDL can override workflow by repo, keyed by owner/repo.\n* CLI--workflowstill wins over config.\n* Repo override wins over fleet/default workflow.\n* Invalid configured workflow values fail closed with a useful error.\n* Dry-run/print output, reservation records, container env/labels, seed prompts, docs, and tests all show the resolved workflow.\n* Existing explicit--workflow direct-mainand--workflow patch-onlybehavior keeps working.\n\n## Sketch\n\nOne plausible KDL shape:\n\nkdl\nsmart-defaults {\n agent-workflow default=\"pr\" {\n repo \"coilyco-flight-deck/agentic-os\" workflow=\"direct-main\"\n repo \"coilyco-flight-deck/ward\" workflow=\"pr\"\n }\n}\n\n\nUse the repo key that is already resolved by dispatch (agentIssueRef.repoSlug()), not cwd discovery, so bare refs and full refs behave the same.\n\n## Acceptance\n\n* Unit tests cover built-in default, KDL default, repo override, CLI precedence, invalid values, and env/label projection.\n*docs/agent-workflow.mdis updated to describe PR as the default and config override precedence.\n*docs/FEATURES.mdis updated if this changes the feature inventory."}, {"repo": "coilyco-flight-deck/ward", "title": "Make PR workflow create, wait, and merge pull requests", "body": "## Goal\n\nChange--workflow prfrom a branch-and-human-gate prompt into a complete ward landing workflow for Forgejo engineers.\n\nToday PR workflow only tells the container agent to push a branch and open a pull request, then it stops. The requested default change needs PR mode to be a real autonomous path first: create the PR, wait for Forgejo Actions or required status checks to finish, run the existing review gate after CI is green, then merge the PR with a merge commit.\n\n## Context read before filing\n\n*cmd/ward/agent_workflow.gocurrently documentspras branch + PR with a human or follow-up loop landing it.\n*docs/agent-workflow.mdsays the same and names this as a first-slice limitation.\n*docs/ward-kdl/ward-kdl.forgejo.write.guardfile.mdcurrently denies PR view/list and says PRs are read through the web UI.\n* The Forgejo swagger lock already contains pull request, action task, branch protection, and merge related shapes, so this is a product/guarded-surface gap rather than an API absence.\n\n## Desired behavior\n\n* Forgejoprworkflow opens a real pull request againstmainfrom the feature branch.\n* Ward waits for CI/status checks for that PR branch/head before review and merge.\n* Ward runs the existing in-container review gate only after CI is green.\n* Ward merges with a merge commit, not squash, rebase, or fast-forward.\n* The issue close path is preserved through the PR body or merge commit message usingcloses #N.\n* Failure to create the PR, green CI, pass review, or merge is reported as blocked/failed with useful context on the issue.\n* GitHub behavior stays compatible with the existing GitHub PR lane.\n\n## Notes\n\nThis should not rely on the agent improvising hiddencurlcalls. Prefer a ward-owned helper or guarded Forgejo verbs with tests around request shape, polling behavior, and failure classification."}]Researched and posted automatically by
ward agent advisor --harness goose(ward#179). This is one-shot research, not a carried change - verify before acting on it.— Goose, via
ward agentWARD-RESERVATION: held 🔒
reservation details
Holder: container
engineer-codex-agentic-os-345on hostkais-macbook-pro-2.local.Reserved by
ward agent --harness codex(reserved 2026-07-09T21:32:53Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (1h TTL).--forceoverrides.Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh. That is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).
run seed context — what this run is carrying (ward#609)
coilyco-flight-deck/agentic-os#345· branchissue-345· harnesscodex· workflowdirect-to-mainengineer-codex-agentic-os-345· wardv0.493.0· dispatched2026-07-09T21:32:53ZStatic container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.493.0).
— Codex, via
ward agentWARD-OUTCOME: done ✅
details
workflow: direct-main; review summary: skipped by ~/.ward/config.yaml default
implementation felt: straightforward bundle/docs/test update, with one merge detour for upstream docs.
confidence: high
surprises: the remote main advanced during the run, and the Go caches were initially too full to let the hooks build.
follow-ups: none