Skip to content

docs: add DevOps deployment flow example#12

Merged
renasami merged 2 commits intomainfrom
docs/devops-flow-example
Apr 18, 2026
Merged

docs: add DevOps deployment flow example#12
renasami merged 2 commits intomainfrom
docs/devops-flow-example

Conversation

@renasami
Copy link
Copy Markdown
Owner

@renasami renasami commented Apr 18, 2026

Summary

  • examples/devops-flow.ts を追加。TegataServer を実利用する CI/CD シナリオ(deploy-bot + 4 tools + 2 policies)のエンドツーエンド例
  • 各 tool で auto-approved / escalated / review の各経路が踏まれるよう設計。期待挙動を main() がサマリ出力
  • eslint.config.mjsignoresexamples/ を追加(tsconfig の include: [\"src\"] 外なので projectService check が失敗するため)

Why

v0.1 の MCP binding がマージされたあと、README の snippet 以外に「動く例」が無かった。ADR-005 が説明する composition 設計を具体的に触れる形で示すのが目的です。

Notes for reviewers

  • transport 接続は commented-out にしてあるので、サンプルを import しても実 server は立たない(import.meta.url guard 付き)
  • examples/ を tsconfig に含めるか別途 tsconfig.examples.json を切るかは要議論。今回は ignore で一旦通した
  • 将来 examples/ をランタイムテストする場合は ignores 撤去 + 専用 tsconfig の方向で

Test plan

  • pnpm run typecheck pass
  • pnpm run lint pass(prettier + eslint)
  • pnpm tsx examples/devops-flow.ts で設定サマリが出力されることを手元で確認(レビュー時に実行推奨)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores

    • Adjusted linting so example files are excluded from type-aware lint checks.
  • Documentation

    • Added a new DevOps workflow example demonstrating runtime/server setup, agent capabilities, review policies with multi-review and escalation, and sample tool handlers for deployment and maintenance.

Adds `examples/devops-flow.ts` demonstrating the MCP binding in a
realistic CI/CD scenario:

- deploy-bot agent scoped to staging with maxApprovableRisk 40
- production policy requiring majority review with escalateAbove 80
- log-deletion policy forcing peer review unconditionally
- four MCP tools (read, staging deploy, production deploy, log delete)
  wrapped by TegataServer, each tagged with actionType and risk metadata

Also adds `examples/` to the ESLint `ignores` list since the directory
sits outside tsconfig's `include: ["src"]` and would otherwise fail
the `projectService` check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f7e1fb98-551b-4917-b519-16dacdb00b6b

📥 Commits

Reviewing files that changed from the base of the PR and between f846b34 and fa4f6be.

📒 Files selected for processing (2)
  • eslint.config.mjs
  • examples/devops-flow.ts
✅ Files skipped from review due to trivial changes (1)
  • eslint.config.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • examples/devops-flow.ts

📝 Walkthrough

Walkthrough

Adds an ESLint flat-config override to disable type-aware linting for examples/**/*.ts and introduces a new example examples/devops-flow.ts that wires a Tegata runtime to an MCP server, registers an agent, policies, and tool handlers, and includes a runnable main() demo.

Changes

Cohort / File(s) Summary
ESLint flat-config override
eslint.config.mjs
Added an override for examples/**/*.ts applying the non-type-checked rule set and explicitly disabling type-aware parsing by setting parserOptions.projectService to false and parserOptions.project to null.
Devops example
examples/devops-flow.ts
New example that builds a Tegata runtime + McpServer/TegataServer, defines demoReviewer, registers an agent (deploy-bot) with capabilities, two review policies (production and logs-delete), four stub tool handlers (ci-status, deploy-staging, deploy-production, delete-logs), a setup() and runnable main() demonstrating expected outcomes.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer/CLI
    participant Tegata as Tegata Runtime
    participant MCP as McpServer
    participant Server as TegataServer
    participant Tools as Tool Handlers
    participant Reviewer as demoReviewer

    Dev->>Tegata: setup() register agent, policies
    Tegata->>MCP: create server instance
    MCP->>Server: wrap McpServer in TegataServer
    Server->>Tools: register tool handlers
    Dev->>Server: submit proposal (client)
    Server->>Tegata: evaluate proposal
    Tegata->>Reviewer: request review decision
    Reviewer-->>Tegata: approve/deny
    Tegata->>Tools: invoke tool action (if approved)
    Tools-->>Server: return CallToolResult
    Server-->>Dev: respond with outcome
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped through configs, gentle and spry,
Disabled the types where examples lie,
I stitched a server, agents in tow,
Policies set, and tools in a row,
A tiny rabbit cheers: watch the demo go!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'docs: add DevOps deployment flow example' accurately reflects the main changes: adding a new example file (examples/devops-flow.ts) and supporting ESLint configuration updates to enable linting of the examples directory.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/devops-flow-example

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

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a DevOps deployment flow example and updates the ESLint configuration to ignore the examples directory. The review feedback suggests maintaining static analysis for example code to ensure quality, removing redundant Promise wrapping in an async function, and fixing a potential cross-platform path comparison bug in the example's entry point.

Comment thread eslint.config.mjs Outdated
export default tseslint.config(
// Ignore build output and config files without tsconfig coverage
{ ignores: ["dist/", "node_modules/", "vitest.config.ts"] },
{ ignores: ["dist/", "node_modules/", "examples/", "vitest.config.ts"] },
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

ESLint の ignoresexamples/ を追加すると、サンプルコードの静的解析が行われなくなります。README で「動く例」として紹介するコードの品質を担保するため、tsconfig.jsonincludeexamples/ を追加するか、専用の tsconfig.examples.json を用意して型チェックとリンターを有効にすることを推奨します。作者が「Notes for reviewers」で述べている通り、将来的なランタイムテストの導入を見据えても、早期にリンターを有効化しておくことが望ましいです。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — fixed in fa4f6be. Moved examples/ out of the top-level ignores and added a scoped override that spreads tseslint.configs.disableTypeChecked and sets projectService: false / project: null, so style and safety rules still run even though the directory sits outside tsconfig.json's include: ["src"].

Comment thread examples/devops-flow.ts Outdated
Comment on lines +85 to +97
return await Promise.resolve(
hasRollback
? {
status: "approved",
decidedBy: "sre-lead",
reason: "rollback plan documented",
}
: {
status: "denied",
decidedBy: "sre-lead",
reason: "no rollback plan provided",
},
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

ここでの await Promise.resolve() の使用は冗長です。関数が既に async として宣言されているため、単にオブジェクトを返すだけで Promise としてラップされます。また、ハンドラー呼び出しを Promise.resolve().then() でラップするという一般的なルールは、同期/非同期のエラーを統一的に扱うための「呼び出し側」(この場合は src/core/runtime.ts 内の Tegata ランタイム)に向けたものであり、ハンドラーの実装自体で行う必要はありません。

  return hasRollback
    ? {
        status: "approved",
        decidedBy: "sre-lead",
        reason: "rollback plan documented",
      }
    : {
        status: "denied",
        decidedBy: "sre-lead",
        reason: "no rollback plan provided",
      };
References
  1. 同期スローと非同期リジェクションの両方を一貫して処理するために、ハンドラーの呼び出しを Promise.resolve().then().catch() チェーンでラップする。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in fa4f6be. Agreed — the Promise.resolve(...) wrapper was a leftover from before the function was async. Removed; the function now returns the literal and the async declaration does the Promise wrapping.

Comment thread examples/devops-flow.ts Outdated
}

// Only run when executed directly (not when imported by tests/tools).
if (import.meta.url === `file://${process.argv[1] ?? ""}`) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

この比較は Windows 環境で失敗する可能性があります。process.argv[1] は Windows ではバックスラッシュ (\) を含みますが、import.meta.url は常にスラッシュ (/) を使用するためです。クロスプラットフォームでの互換性を保つためには、パスを正規化して比較することをお勧めします。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Fixed in fa4f6be. Replaced the string comparison with fileURLToPath(import.meta.url) === process.argv[1] via node:url, which normalizes to the native filesystem path on both POSIX and Windows.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f846b348bf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread examples/devops-flow.ts Outdated
Comment on lines +56 to +57
capabilities: ["ci:*:read", "ci:staging:*"],
maxApprovableRisk: 40,
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 Configure deploy-bot to allow the review-path example

The delete-logs flow is described as a review-tier example, but with this agent registration it is unreachable: deploy-bot has only ci:*:read/ci:staging:* and maxApprovableRisk: 40, while the tool uses ci:logs:delete with riskScore: 70. In Tegata.propose() (capability and agent-risk checks), either condition escalates before policy review handlers run, so this path will always be escalated rather than reviewed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Good catch — fixed in fa4f6be. The better fix is to make the review tier actually reachable, since demonstrating it is the whole point of the tool. Added ci:logs:delete to deploy-bot's capabilities and lowered the delete-logs tool to riskScore: 35 (within maxApprovableRisk: 40). Capability + risk checks now pass and the proposal reaches the policy layer, which forces review.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
eslint.config.mjs (1)

6-6: Keep examples/ linted with a dedicated override instead of fully ignoring it.

Line 6 currently disables all lint checks for example code. That makes the sample likely to drift from repo standards. Prefer a scoped override (disable only type-aware rules for examples) so style/safety rules still run.

♻️ Suggested config adjustment
-  { ignores: ["dist/", "node_modules/", "examples/", "vitest.config.ts"] },
+  { ignores: ["dist/", "node_modules/", "vitest.config.ts"] },
+
+  // Examples: linted, but not type-aware (outside main tsconfig include)
+  {
+    files: ["examples/**/*.ts"],
+    ...tseslint.configs.disableTypeChecked,
+    languageOptions: {
+      parserOptions: { projectService: false },
+    },
+  },

As per coding guidelines **/*.{ts,tsx}: “Use TypeScript strict mode with no any types” and “Enforce import type …”, which should remain enforced for TypeScript files, including examples.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@eslint.config.mjs` at line 6, Remove "examples/" from the top-level ignores
array and instead add an overrides entry that targets "examples/**/*.{ts,tsx}"
so example files remain linted; in that override disable type-aware rules by
clearing parserOptions.project (set to undefined/null) or explicitly turning off
the type-info rules so style and non-type rules still run while skipping rules
that require type-checking. Update the file's ignores array (remove "examples/")
and add an overrides object with a pattern for examples and the
parserOptions/rules change to scope the exception.
examples/devops-flow.ts (1)

60-63: Avoid process.exit(1) during module initialization.

These exits run before the direct-exec guard (Line 310), so an import can terminate the caller process if setup ever fails. Move setup/error-exit behind main() execution path (or return an error from setup and let the direct-run block decide whether to exit).

Also applies to: 117-120, 130-133

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@examples/devops-flow.ts` around lines 60 - 63, The code currently calls
process.exit(1) during top-level setup when registerResult.ok is false (and in
other top-level checks around the registerResult logic), which can terminate the
importer; change the pattern so setup returns an error instead of exiting: move
the register call and its failure handling into the main execution path (e.g.,
inside main() or a setupAsync() function), or have registerAgent()/setup
functions throw or return a Result that main() inspects and then call
process.exit only from the direct-exec guard; update the failure handling for
the other top-level checks (the blocks at the other noted spots) to follow the
same pattern and remove direct process.exit calls from module initialization.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@examples/devops-flow.ts`:
- Line 18: Update the documentation entries so that the "delete-logs" action is
marked as "escalated" (not "review tier"): change the listing at the top (line
18) and the detailed example block (lines ~264–267) to state that "delete-logs"
is escalated due to the deploy-bot lacking the ci:logs:delete capability (it
only has ci:*:read and ci:staging:*) and because the action's riskScore (70)
exceeds deploy-bot's maxApprovableRisk (40); reference the runtime checks in
src/core/runtime.ts (the capability check around the proposer capability logic
and the risk check) when updating the explanatory text so it explicitly cites
"capability gap + riskScore > maxApprovableRisk" as the reason for escalation.

---

Nitpick comments:
In `@eslint.config.mjs`:
- Line 6: Remove "examples/" from the top-level ignores array and instead add an
overrides entry that targets "examples/**/*.{ts,tsx}" so example files remain
linted; in that override disable type-aware rules by clearing
parserOptions.project (set to undefined/null) or explicitly turning off the
type-info rules so style and non-type rules still run while skipping rules that
require type-checking. Update the file's ignores array (remove "examples/") and
add an overrides object with a pattern for examples and the parserOptions/rules
change to scope the exception.

In `@examples/devops-flow.ts`:
- Around line 60-63: The code currently calls process.exit(1) during top-level
setup when registerResult.ok is false (and in other top-level checks around the
registerResult logic), which can terminate the importer; change the pattern so
setup returns an error instead of exiting: move the register call and its
failure handling into the main execution path (e.g., inside main() or a
setupAsync() function), or have registerAgent()/setup functions throw or return
a Result that main() inspects and then call process.exit only from the
direct-exec guard; update the failure handling for the other top-level checks
(the blocks at the other noted spots) to follow the same pattern and remove
direct process.exit calls from module initialization.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c41b08a2-f53a-40b3-99ba-f0727f02e082

📥 Commits

Reviewing files that changed from the base of the PR and between 12a1f98 and f846b34.

📒 Files selected for processing (2)
  • eslint.config.mjs
  • examples/devops-flow.ts

Comment thread examples/devops-flow.ts Outdated
- eslint.config.mjs: re-enable linting for examples/ via a scoped
  override that disables type-aware rules only (style/safety rules
  still run), per CodeRabbit + Gemini review.
- examples/devops-flow.ts:
  - Move setup out of module scope into a setup() Result function
    called from main(); no more process.exit() side-effects on
    module import.
  - Drop redundant `await Promise.resolve(...)` in demoReviewer —
    async already wraps the return.
  - Replace `import.meta.url === file://${process.argv[1]}` guard
    with `fileURLToPath()` for cross-platform path comparison.
  - Fix delete-logs review-tier demonstration: give deploy-bot the
    `ci:logs:delete` capability and lower riskScore to 35 so the
    proposal actually reaches the policy layer instead of escalating
    on agent enforcement.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@renasami
Copy link
Copy Markdown
Owner Author

Review fixes pushed (fa4f6be)

Addressed all 5 inline findings. Summary:

# Reviewer Finding Fix
1 CodeRabbit + Gemini examples/ fully ignored, static analysis lost Scoped ESLint override with disableTypeChecked + projectService: false; style/safety rules still run
2 CodeRabbit process.exit() during module init Setup moved into setup() Result function, called from main() — no side effects on import
3 Gemini Redundant await Promise.resolve(...) in reviewer Removed; async declaration handles the wrap
4 Gemini Windows path comparison fileURLToPath(import.meta.url) === process.argv[1]
5 Codex + CodeRabbit delete-logs escalates before review Reconfigured: added ci:logs:delete capability + lowered riskScore to 35, so the review tier is actually reached

Verified with pnpm run typecheck, pnpm run lint, and npx tsx examples/devops-flow.ts (prints the summary and exits cleanly).

@renasami
Copy link
Copy Markdown
Owner Author

@gemini review

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a DevOps deployment flow example and updates the ESLint configuration to accommodate the new examples directory. Feedback includes a recommendation to enable type-aware linting for examples via a dedicated tsconfig to prevent API misuse, and a suggestion to improve the robustness of the entry point check in the example script by resolving process.argv[1] to an absolute path.

Comment thread eslint.config.mjs
Comment on lines +99 to +104
files: ["examples/**/*.ts"],
...tseslint.configs.disableTypeChecked,
languageOptions: {
parserOptions: { projectService: false, project: null },
},
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

examples/ ディレクトリに対して型情報が必要なルール(type-aware rules)を無効化していますが、これにより example コード内での API の誤用や型不整合を検知できなくなるリスクがあります。PR の説明にある通り、長期的には tsconfig.jsoninclude に追加するか、専用の tsconfig.examples.json を用意して、example コードに対しても型チェックを伴う静的解析を有効にすることを推奨します。

Comment thread examples/devops-flow.ts
// `fileURLToPath` normalizes `import.meta.url` to a native filesystem
// path, which matches `process.argv[1]` on both POSIX and Windows.
const entryPoint = process.argv[1];
if (entryPoint !== undefined && fileURLToPath(import.meta.url) === entryPoint) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

process.argv[1] は実行方法(例: node examples/devops-flow.ts)によっては相対パスになる可能性があるため、絶対パスを返す fileURLToPath(import.meta.url) との比較が失敗する場合があります。より堅牢にするには、process.argv[1]path.resolve() で絶対パスに変換してから比較するか、import.meta.urlpathToFileURL(process.argv[1]).href を比較することを検討してください。

@renasami renasami merged commit 1e44b0f into main Apr 18, 2026
2 checks passed
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.

1 participant