Skip to content

feat(sdk): YAML helper verbs compile to effect steps (#345) - #349

Merged
kjgbot merged 4 commits into
mainfrom
feat/spec-V-yaml-helpers
Sep 12, 2026
Merged

kjgbot merged 4 commits into
mainfrom
feat/spec-V-yaml-helpers

Conversation

@kjgbot

@kjgbot kjgbot commented Sep 11, 2026 •

Copy link
Copy Markdown
Contributor

Closes #345. Delivered via implement-slice.flow.ts (flows-driven dogfood, mixed codex/claude).


Note

Medium Risk
Changes compile-time lowering, preflight refusals, and shared provider writeback/effect completion paths used by workers and Slack helpers; mistakes could affect idempotency or external side effects without touching kernel step types.

Overview
Adds YAML helper verbs for Slack, GitHub, and Linear so flow steps can declare a single provider action (e.g. slack.post) instead of hand-authored agent steps. During compileSpec, expandYamlHelpers lowers each helper step to a normal agent step: a versioned relayflows:helper:v1 instruction, recoveryMode: reset, and an external surface (/slack, /github, /linear). Arguments are literal JSON only (AJV schemas per verb); unknown providers, verbs, or fields fail at compile time.

Runtime reuses the existing journal effect election and receipt durability: new yaml-helper-effect centralizes dispatch (Slack still uses slackWriteback; GitHub/Linear use relayfile writeJsonFile). AgentWorker, authored Slack effects, and flows check all route through completeHelperDispatch / helperReady instead of duplicating Slack-only completion logic.

Preflight skips CLI resolution for helper steps and adds a helper_mount_required refusal when the provider directory is missing under the relayfile mount env vars (Slack can satisfy readiness via RELAYFLOWS_SLACK_MOCK). Public types YamlFlowSpec, YamlHelperStepSpec, and YamlHelperParams are exported; docs/YAML-HELPERS.md documents authoring and local run. Unit tests cover expansion, invocation, effect recovery, and live CLI integration; spec-V evidence logs are added separately.

Reviewed by Cursor Bugbot for commit 1e507e3. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Sep 11, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 52579b18-a8ca-4b78-833f-3109e6d7c5f6


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit be01d64. Configure here.

Comment thread packages/sdk/src/failure-kinds.ts
@kjgbot

kjgbot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

maintainability lens — FAIL

Maintainability review — PR #349

Blockers

  • evidence/spec-V/sdk-tests.txt (839 lines) — the file is committed as "evidence" but is a wall of failures: EPERM on Unix sockets, ENOSPC on tmp, timeouts on cli-watch.test.ts (lines 675–719), and 194 failed suites near the tail. A stranger in six months has no way to tell what the acceptance actually was. AGENTS.md §"Evidence is captured, not narrated" makes this the exact anti-pattern to avoid; either land a green transcript or drop the file. evidence/spec-V/test-typecheck.txt is a zero-byte file with no context (line 1).
  • packages/sdk/tsconfig.slice-v.tmp.json — one-line, .tmp.json-named, missing trailing newline. Committing a temporary tsconfig with slice-v in its name broadcasts unfinished work and will be indistinguishable from a real config once the branch name fades.

Concerns

  • helperMount (yaml-helper-effect.ts:11–17) duplicates slackMount (slack-preflight.ts:5–11) byte-for-byte except for the provider directory name. The env-var order is an implicit contract; two copies means the next env addition silently drifts. Fold slackMount through helperMount('slack') or extract a single mount resolver.
  • readSlackReceipt is now called for GitHub and Linear (yaml-helper-effect.ts:63, 75). The name asserts Slack-specific behavior that the code no longer has; a reader debugging a Linear crash won't grep for "Slack." Same for the exported receiptPath living in slack-writeback.ts. Rename or move.
  • The generic writeback branch weakens Slack's receipt discipline (yaml-helper-effect.ts:27–36 vs slack-writeback.ts:59–60). Slack rejects a receipt missing externalId/ts; the generic path only checks result.receipt is truthy, so an empty {} succeeds. This is exactly the "tests that would not fail if the behavior broke" pattern — no unit exercises a stub returning {deliveryStatus:'confirmed', receipt:{}} for GitHub/Linear.
  • helperReady (yaml-helper-effect.ts:20–22) special-cases RELAYFLOWS_SLACK_MOCK for Slack only. GitHub/Linear have no mock path, so preflight in CI without a mount will refuse them while Slack passes. The asymmetry is invisible from the call site in cli/check.ts:274.
  • AgentWorker.execute (worker.ts:101–104) throws a raw Error when dataDir is missing instead of failing the step with a completionReason. AGENTS.md §"Fail closed" and Covenant 2 require typed failure. This is preflightable — helper && !dataDir should refuse before dispatch, not throw mid-worker.
  • expandYamlHelpers error prefixing is inconsistent (yaml-helpers.ts:96–103): the "no providers" branch calls helperCall(step) outside the try/catch, so a corrupted canonical envelope throws without the spec.steps[${index}]: prefix that the sibling branch adds. Move that call inside the try or wrap it.

Notes

  • authored-slack-effect.ts is now a ~90-line shell that just assembles a dispatch and defers to completeHelperDispatch. Consider deleting once the last authored Slack caller migrates.
  • OneKey<T> and the YamlHelperStepSpec intersection (spec.ts:246–252) are dense; a one-line comment stating "exactly one provider, exactly one verb" would save a reader ten minutes.
  • Docs (docs/YAML-HELPERS.md) are clear and correctly name the mount env vars.

REVIEW_FAILED

@kjgbot

kjgbot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

history lens — PASS

Blockers: none under the three HISTORY criteria.

The supplied diff does not show a previously removed pattern being restored or a new contradiction with a settled RFC decision. Commit be01d64d says “YAML helper verbs compile to effect steps”; its body is empty. That describes the implementation and makes no claims about passing tests, mutation verification, or completed acceptance gates.

Notes

Concerns, nonblocking for this lens

The committed npm test transcript is not green. evidence/spec-V/sdk-tests.txt, lines 28–30 contains:

 ❯ tests/preflight.test.ts (27 tests | 1 failed) 36ms

The refusal-enumeration assertion needs attention alongside the new helper_mount_required kind. This failure should not be dismissed with the socket-permission failures elsewhere in the transcript. However, a failing assertion alone does not establish one of this lens’s three rejection grounds, and the commit does not misrepresent it.

The empty evidence/spec-V/test-typecheck.txt supplies no affirmative verification evidence. I did not rerun tests; this verdict is limited to historical compatibility and claim accuracy.

REVIEW_PASSED

@kjgbot

kjgbot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

structure lens — MISSING

@kjgbot

kjgbot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

🎯 review-swarm: FAILED (M:fail H:pass S:missing)

Lens transcripts posted as sibling comments above.

miyaontherelay and others added 3 commits September 12, 2026 01:51
Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
Adds a scenario producing a Slack helper step with `helper: () => false`
so the refusal-kind walker covers the kind added in V. Restores the
Set(refusalKinds).toEqual(Set(PREFLIGHT_FAILURE_KINDS)) invariant.

Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82

Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
CI runners have rustup installed but no default cargo configured, so
`ops/cargo.sh metadata` fails with "rustup could not choose a version of
cargo to run". The prebuilt kernel binary is already shipped to the test
via RELAYFLOWD_BIN — the metadata query was only needed to LOCATE it
when the env var was unset. Short-circuit on the env var (matching the
pattern live-kernel.test.ts uses) so CI stops attempting the cargo call
it can't satisfy.

Refs #349

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
@kjgbot
kjgbot force-pushed the feat/spec-V-yaml-helpers branch from 72c68e8 to e6d8ddf Compare September 11, 2026 23:52
Slice Y widened SlackPostMessage.text to string | SlackBlock[]; YAML
dialect only surfaces string, so cast at the verb boundary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Session-Id: efeda5df-9b7c-48d4-b2ce-957f5bef0a82
@kjgbot
kjgbot merged commit dc22c1e into main Sep 12, 2026
8 of 10 checks passed
@kjgbot
kjgbot deleted the feat/spec-V-yaml-helpers branch September 12, 2026 00:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

flows: V — YAML helper verbs (slack: {post: '#chan'} compile-time expansion)

2 participants