Repository navigation
fix(registry/coder/modules): clean relay state on stop and start - #1212
Merged
Merged
Conversation
Contributor
Module Scorecard Check
|
| Theme | Before | After |
|---|---|---|
| Presentation & Onboarding | 12 / 17 | 12 / 17 |
| Integration | 10 / 25 | 10 / 25 |
| Credential Hygiene | 20 / 20 | 12 / 20 |
| Restricted-Environment | 12 / 20 | 13.5 / 20 |
| Engineering Quality | 10 / 10 | 10 / 10 |
| Overall | 70 / 100 | 63 / 100 |
Full scorecard for this PR
| Presentation & Onboarding | Agent Integration | Credential Hygiene | Restricted-Environment Readiness | Engineering Quality | Overall |
|---|---|---|---|---|---|
| 12 / 17 | 10 / 25 | 12 / 20 | 13.5 / 20 | 10 / 10 | 63 / 100 |
Drilldown
Presentation & Onboarding — 12 / 17
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Configuration-mode examples | 12 | 12 | README gives worked examples for the major configuration axes: install_cli true/false (BYOI vs. download), additional_args, release_idle_session_min override, and health_port override, each with a code block and sensible defaults called out. |
| Visual preview | 5 | 0 | No image, GIF, or video anywhere in the README. |
Credential Hygiene — 12 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Secrets marked sensitive | 16 | 8 | agent_relay_credential uses ephemeral = true and styling.mask_input = true, but no resource in main.tf sets sensitive = true (not present on coder_parameter or coder_env here). README never shows an inline/placeholder key, so half credit for avoiding inline secrets without the literal sensitive-flag convention. |
| Non-hardcoded auth path | 4 | 4 | Credentials are never pasted by a human; Agent Relay stamps a single-use JWT into a disabled, masked parameter and the module wires it to SELF_HOSTED_RUNNER_ENVIRONMENT_SECRET via coder_env — a documented non-manual auth path. |
Restricted-Environment Readiness — 13.5 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Mirrorable artifact source | 5 | 0 | install.sh.tftpl hardcodes curl https://claude.ai/install.sh -fsSL | bash; no module variable overrides this download URL. |
| Bring-your-own binary | 10 | 10 | install_cli = false fully skips the download, documented in the README ("Bake the CLI into the image and set this to false for faster workspaces") and in Requirements. |
| Egress transparency | 3 | 1.5 | claude.ai/install.sh is mentioned in the Requirements section and in script comments, but there is no dedicated "network/egress" section enumerating contacted endpoints — scattered mentions cap this at half. |
| Runs without sudo | 2 | 2 | install.sh.tftpl, start.sh.tftpl, and cleanup.sh.tftpl never invoke sudo; all operations (curl install, process management, file writes) run as the invoking user. |
Engineering Quality — 10 / 10
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Input quality | 6 | 6 | Every variable has a clear description and default; several carry validation blocks (cli_binary regex, exit_if_unused_min, release_idle_session_min 0–10080 bound, health_port 0–65535, additional_args reserved-flag and newline checks). |
| Test coverage | 4 | 4 | Large main.tftest.hcl covers parameter contract, env wiring, script rendering business logic; main.test.ts runs full end-to-end container tests against a stubbed CLI covering lifecycle, cleanup races, idle release, and injection safety. |
Agent Integration — 10 / 25
| Criterion | Max | Score | Notes |
|---|---|---|---|
| AI governance | 10 | 0 | No mention of Coder AI Gateway or Agent Firewall anywhere in the README. |
| Dashboard entry point | 5 | 0 | No coder_app resource or documentation of one; the module only renders coder_script/metadata outputs. |
| Session continuity | 5 | 5 | "Idle session release" section explicitly documents native resume: an idle session is released server-side and "the user's next message resumes the session on a fresh runner." |
| Managed configuration | 5 | 5 | base_dir variable is documented as the configured workdir (CLI's --base-dir), with rationale for why the module always sets its own value rather than the CLI default. |
Overall — 63 / 100
Raw 57.5 / 92 → round(57.5 / 92 × 100) = 63
coder/agent-relay-cursor: 51 → 49
| Theme | Before | After |
|---|---|---|
| Presentation & Onboarding | 6 / 17 | 6 / 17 |
| Integration | 5 / 25 | 5 / 25 |
| Credential Hygiene | 12 / 20 | 12 / 20 |
| Restricted-Environment | 13.5 / 20 | 12 / 20 |
| Engineering Quality | 10 / 10 | 10 / 10 |
| Overall | 51 / 100 | 49 / 100 |
Full scorecard for this PR
| Presentation & Onboarding | Agent Integration | Credential Hygiene | Restricted-Environment Readiness | Engineering Quality | Overall |
|---|---|---|---|---|---|
| 6 / 17 | 5 / 25 | 12 / 20 | 12 / 20 | 10 / 10 | 49 / 100 |
Drilldown
Presentation & Onboarding — 6 / 17
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Configuration-mode examples | 12 | half | README gives a primary usage example plus additional_args and management_addr override snippets, but computer_use/share_desktop (a major opt-in mode requiring extra image packages) and install_cli = false are only discussed in prose (Requirements section), with no dedicated code example for each mode. |
| Visual preview | 5 | 0 | No image, GIF, or video anywhere in the README. |
Agent Integration — 5 / 25
| Criterion | Max | Score | Notes |
|---|---|---|---|
| AI governance | 10 | 0 | No mention of Coder AI Gateway or Agent Firewall anywhere in the README; auth/routing is handled entirely through Agent Relay's own claim/session-token model, not Coder's governance primitives. |
| Dashboard entry point | 5 | full | coder_app.cursor_web and coder_app.cursor_desktop are declared and clearly documented ("Open in Cursor Web" / "Open in Cursor Desktop"), conditioned on a dispatched session. |
| Session continuity | 5 | 0 | No documented resume/session-ID continuity or persistent session manager (tmux/screen/boo) for reconnects; the idle-release/session-attachment machinery governs reaping, not reconnect continuity. |
| Managed configuration | 5 | 0 | No documented support for managed MCP, settings, policies, or workdir configuration. |
Credential Hygiene — 12 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Secrets marked sensitive | 16 | half | agent_relay_credential uses ephemeral = true and styling = { mask_input = true } rather than a literal sensitive = true attribute; no coder_env resource is marked sensitive either. README examples never inline a literal secret, which is good, but the formal "sensitive" marking mechanism specified by the rubric isn't used. |
| Non-hardcoded auth path | 4 | full | Extensive "Worker credential" section documents that the service-account key never leaves Agent Relay, only a short-lived, claim-scoped session token reaches the workspace via --auth-token-file, never on the command line or in the template. |
Restricted-Environment Readiness — 12 / 20
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Mirrorable artifact source | 5 | 0 | install.sh.tftpl hardcodes curl https://cursor.com/install -fsSL | bash. No module variable (e.g. cli_binary, management_addr) overrides the download URL — cli_binary only overrides the binary path/name, not the install source. |
| Bring-your-own binary | 10 | full | install_cli = false (documented in the top example and the Requirements section) skips the download entirely and expects the CLI pre-baked in the image, with cli_binary to point at it. |
| Egress transparency | 3 | 0 | No dedicated network/egress/air-gapped section; cursor.com/install, cursor.com/agents, and the cursor:// deeplink are mentioned only incidentally in unrelated sections, never enumerated together. |
| Runs without sudo | 2 | full | All scripts (install.sh.tftpl, start.sh.tftpl, cleanup.sh.tftpl) run entirely as the invoking user with no sudo calls anywhere. |
Engineering Quality — 10 / 10
| Criterion | Max | Score | Notes |
|---|---|---|---|
| Input quality | 6 | full | Variables have detailed descriptions and sensible defaults, plus strong validation blocks (cli_binary command-safety regex, management_addr host:port + port-range checks, share_desktop requires computer_use, additional_args rejects reserved flags/newlines, serving_log_pattern rejects empty string). |
| Test coverage | 4 | full | main.tftest.hcl covers parameter contract, script wiring, and business logic extensively via plan-time assertions; main.test.ts runs real container-based end-to-end tests of install/start/cleanup lifecycle, PID/boot-id identity verification, and SIGTERM/SIGKILL escalation. |
Overall — 49 / 100
Raw 45 / 92 → round(45 / 92 × 100) = 49
Tip
You can run this locally by telling your agent: "review this module against .github/scorecard/SCORECARD.md".
Scored against SCORECARD.md with solstice-1. Language-model scores are advisory.
Emyrk
force-pushed
the
fix/relay-workspace-start-state
branch
from
October 27, 2026 16:42
8ed3996 to
869b131
Compare
Emyrk
marked this pull request as ready for review
October 28, 2026 19:36
Emyrk
marked this pull request as draft
October 28, 2026 19:43
Emyrk
marked this pull request as ready for review
October 28, 2026 22:02
matifali
approved these changes
Oct 29, 2026
Member
Author
Yes. I've run tests before and after the stop script work. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A relay workspace can restart with its previous runner state on a persistent home volume. The old
workingstate can read asorphaned, an olddonecan look like the new run's result, and a surviving supervisor or worker can compete with the new one. Agent Relay can act on that stale status before the new run publishes its own (RELAY-71).Change
run_on_stopcleanup from one source per module. On graceful stop, cleanup signals verified supervisors and workers, waits up to 10 seconds after TERM and 5 seconds after KILL, and removes state. It does not publish a marker that permits a new launch. Templates need at least 30 seconds of runtime shutdown grace for the 20-second stop-hook timeout plus agent shutdown.idleinstead of a prior run's result. Cursor removes its stale token before reportingidle./procstart time match its record. Keep unverifiable records for a later attempt.Availability tradeoff: Startup fails open if the old process survives or cannot be verified. Two runners may overlap. A surviving old supervisor can race to write stale status or, for Cursor, remove a new worker's shared token after its generation check. This interference is explicitly accepted for this failure mode, rather than blocking a new work order. A stop hook can also be skipped or cut short; startup cleanup remains the fallback.
Scope: This is module-side cleanup, not a complete RELAY-71 fix. Agent Relay still needs new-build status-settling grace because it may sweep before cleanup or fresh metadata. The reaper work is separate.
Validation
bun run fmt, targeted Prettier and Terraform formatting checks,bun run check:validatefor both modules, andgit diff --check.Decision log for reviewers
coder-utilspre-install step, and add a separatecoder_scriptwithrun_on_stopfrom the same per-module source. The stop mode never writes a fresh launch marker./procstart time before TERM or KILL; no pidfd helper. Remove status before signalling, wait, then remove it again.Generated by Coder Agents for @Emyrk.