Skip to content
Draft
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
6 changes: 6 additions & 0 deletions k8s/providers/hetzner/apps/agentic-engineer/harness.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ metadata:
namespace: agentic-engineer
spec:
claude: {}
# The lane's own harness image, pinned by digest as kagent requires: kagent's
# Claude harness plus the engineer's tools and the whole agentic-engineering
# plugin (scripts/kagent-claude-harness, devantler-tech/monorepo#4867, #4868).
# Main publishes and signs it; move this pin after each publish.
workload:
image: ghcr.io/devantler-tech/platform-kagent-claude-harness@sha256:5777ced3082c426842d7d43e73869d3cdc8828f93ec96ce78c9a30b558862097
substrate:
workerPoolRef:
name: agentic-engineer
Expand Down
51 changes: 37 additions & 14 deletions k8s/providers/hetzner/apps/agentic-engineer/job-schedule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,9 @@ spec:
- name: TIME_ZONE
value: Europe/Copenhagen
# Paused until every sub-issue of devantler-tech/monorepo#4866 is
# done (ADR 0014, point 6). The canary runs once, started from the
# kagent UI; the PR that swaps in the full run message unpauses it.
# done (ADR 0014, point 6). The full run is first tried once, started
# from the kagent UI with "run now", which works while paused; the
# PR that unpauses it follows that run and the maintainer's go-ahead.
- name: PAUSED
value: "true"
# A run has no time limit: cutting one off mid-task wastes what it
Expand All @@ -86,20 +87,42 @@ spec:
# reaches.
- name: EXECUTION_TIMEOUT
value: 315360000s
# The current message is the canary (devantler-tech/monorepo#4869):
# it proves the model, GitHub and Git paths and changes nothing.
# The full engineering run replaces it once the canary has passed.
# The full run: the same thin pointer the host lanes' scheduler
# entries use, plus the lane store, because each run starts in a
# fresh sandbox (devantler-tech/monorepo#4869). The role itself
# comes from the agentic-engineering plugin in the harness image,
# never from this prompt.
- name: PROMPT
value: |
Canary run. Change nothing: create no branch, commit, issue, comment or
pull request.
1. Name the model you are running as.
2. Run `git -c http.extraHeader='Authorization: Basic kagent-credential-injected' ls-remote https://github.com/devantler-tech/monorepo.git HEAD`
and report the commit it prints.
3. Shallow-clone that repository the same way and report the first line of
its AGENTS.md.
4. Report which of the commands gh, curl, jq and yq exist in your sandbox.
Reply with a short report of each step and anything that failed.
Scheduled run of the devantler-tech Agentic Engineer on its kagent lane:
instance `kagent-cluster`, writer namespace `kagent/*`, one run a day.

1. Restore your native memory from the lane store. List memory/ with a
WebDAV PROPFIND (`curl -fsS -X PROPFIND -H 'Depth: 1'` plus the store
header) and download every file into ~/lane-memory/. Only a 404 for
memory/ means a first run, so start with an empty ~/lane-memory/. Any
other failure means the store is unreachable: stop and report it.
Comment on lines +100 to +104

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire the lane store before requiring it as the first step

When the paused schedule is started with “run now,” this first step requires a store connection that the reviewed tree does not configure. The Harness supplies only GH_TOKEN, and agent.yaml selects only the github EgressPolicy, whose destinations contain no WebDAV store. A repository-wide search for WebDAV/lane-store configuration also found no endpoint or store-header definition outside this prompt. Consequently, the run cannot restore memory and must stop before reaching the engineering entrypoint; uploading its report is blocked by the same missing connection. Include the store prerequisite and its egress/authentication wiring before switching the schedule to this prompt.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right for this tree: the store wiring (Deployment, Service, lane-store EgressPolicy, the Agent's reference to it and the system prompt's store address) is platform#6014, which is in the merge queue ahead of this PR. This PR stays a draft until #6014 has merged; I will then merge main into this branch, so the reviewed tree carries the store, and request a fresh review before it is queued. No change to the prompt itself.

🤖 Addressed by Claude Code

2. Shallow-clone devantler-tech/monorepo, read its AGENTS.md, load the
agentic-engineering plugin and invoke its agentic-engineer entrypoint
as this scheduled run. ~/lane-memory/ is your native memory (the
legacy layout), as the durable-memory guide says for this lane.
Follow the consumer contract and fail closed on missing deployment
facts. Do not duplicate the role here.
3. Before you stop, however the run ended, upload ~/lane-memory/ back to
memory/ on the lane store, and upload this session's transcript (the
newest Claude Code session JSONL under your Claude config directory)
and your run report to runs/<UTC date>/transcript.jsonl and
runs/<UTC date>/report.md. If an earlier run that day already wrote
them, never replace them: write yours beside them as
transcript-<UTC time HHMMSS>.jsonl and report-<UTC time HHMMSS>.md.
Create a missing folder with MKCOL before writing into it, and check
that every upload succeeded.

This run may open, update and review devantler-tech pull requests and
issues, per AGENTS.md. It never merges. Only when genuinely blocked on a
decision only the maintainer can make, and only after trying to resolve
it yourself, open one public-safe `maintainer-ask` issue, following
AGENTS.md#Maintainer channels.
# Retries of one Job share its uid, so a create whose reply was lost
# returns the schedule it made instead of making a second one.
- name: REQUEST_ID
Expand Down
8 changes: 8 additions & 0 deletions scripts/tests/test-kagent-claude-harness-wrapper.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ manager="$(jq -c '[.customManagers[] | select(.depNameTemplate == "devantler-tec
| select(any(.matchStrings[]; startswith("ARG AGENT_PLUGINS_COMMIT=")))] | length' \
"${root}/.github/renovate.json")"
[[ "${manager}" == 1 ]] || fail 'Renovate does not move the plugin commit'
# The lane's Harness runs this image, pinned by digest as kagent requires; the built-in image has
# neither the tools nor the whole plugin.
command -v yq >/dev/null || fail 'yq is required'
harness_image="$(yq '.spec.workload.image' "${root}/k8s/providers/hetzner/apps/agentic-engineer/harness.yaml")"
[[ "${harness_image}" =~ ^ghcr\.io/devantler-tech/platform-kagent-claude-harness@sha256:[0-9a-f]{64}$ ]] ||
fail "the lane's Harness does not run this image by digest: ${harness_image}"
grep -Fq 'IMAGE: ghcr.io/devantler-tech/platform-kagent-claude-harness' "${root}/.github/workflows/publish-kagent-claude-harness.yaml" ||
fail 'the Harness image is not the one the publish workflow builds'

# The stub Claude Code records its arguments one per line, then its input, and exits with $STUB_EXIT.
cat >"${work}/real-claude" <<'STUB'
Expand Down
Loading