feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476) - #495

Merged
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl
Jul 14, 2026
Merged

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D11 #476)#495
yusuke0610 merged 2 commits into
mainfrom
feat/skill-display-name-hitl

Conversation

@yusuke0610

@yusuke0610yusuke0610 commented Jul 14, 2026

Copy link
Copy Markdown
Owner

概要

issue #476(ADR-0016 D8 の残課題「表示名・粒度の畳み込みの human-in-the-loop 確定」)を D11 として実装。GitHub 連携で検出した package / infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が確認・編集して確定・永続化する一連のフローを追加する。

Closes#476

設計(ADR-0016 D11 として追補)

  • 確定は独立 Layer 3 テーブルに保存: 人間の確定を、連携再実行で洗い替えされる Layer 1-2(github_skills)から切り離した github_skill_display_decisions安定 identity(kind + ecosystem + canonical_name)で保存。これで再連携の洗い替えに耐え、N:1 グルーピングも表現できる(D1「機械=幅 / 人間=深さ」)。
  • agent は提案のみ(D8 / P4): メンバーはリクエストごとの動的 enum で実在スキルに縛り、捏造を構造的に排除(ADR-0018 の手法を踏襲)。確定・DB 更新は人間側。
  • 表示名の解決順(serve 時): 確定値 > 機械 display_name(Linguist)> canonical_name。既存 display_name は機械フォールバックとして温存。
  • 機械制約はスキーマ・品質はプロンプト(ADR-0010 責務分離)。課金・プロバイダ抽象は既存契約を流用(ADR-0012・0013)。

主な変更

backend

  • 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
  • services/agent/skill_display/(proposer + output_schema)+ prompt。リトライ1回・課金 usage の合算・エラー契約はチャット/ドラフトと同一
  • エンドポイント3つ: POST .../skills/display-names/propose(billed・rate limit)/ PUT .../skills/display-decisions(authz 付き確定・バッチ upsert)/ GET .../skills(decision を join)
  • 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用・DRY化)
  • **提案対象は package/infra に限定(language 除外)**し、キャップ 50 件(入力トークン・構造化出力 enum の肥大を抑制。実測 180 件超で顕在化した弱点への対策)

web

  • ダッシュボードにスキル一覧セクション新設 + 「AI 提案 → レビュー/編集 → 確定」導線(SkillDisplaySection
  • 決定論ロジック(表示名解決・グループ化・提案→確定変換)を utils/skillDisplay.ts に切り出し TDD(red→green)
  • ダークモード白飛び対策としてテーマトークン(--bg-section 等)で配色

ドキュメント

  • ADR-0016 に D11 を追補、改訂履歴・「将来課題」記述・索引整合を更新

テスト

  • backend: 新規 test_skill_display_service.py / test_skill_display_api.py(提案パース・捏造メンバー拒否・リトライ・洗い替え後も確定が残ること・confirm の authz・language 除外の 404)。make test-backend 全 pass
  • web: utils/skillDisplay.test.ts / hooks/useGitHubSkills.test.ts(loading/success/error)
  • E2E: github-link に 提案→確定でチップに確定表示名が反映されるフローを追加(全 pass)
  • make ci green / make codegen-types 反映済み(drift なし)

補足

  • 実運用の LLM 品質はローカル Ollama では測れない(小型モデルは大量スキルの構造化 JSON を壊しやすい)。本番の tool use(Sonnet 等)前提。language 除外 + キャップ 50 で入力を軽量化済み。
  • 残課題(ADR に明記): 確定値のバージョニング/監査履歴、group 跨ぎの evidence 重み再計算、agent による足切り提案。

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added an AI-assisted workflow to propose and human-confirm GitHub skill display names, including optional grouping.
    • Added UI to review proposals, edit proposed names, and confirm/discard changes.
    • Confirmed display names and groupings persist and are reflected in the GitHub skill list, even after relinking.
  • Bug Fixes
    • Improved LLM usage/credit logging after AI requests to improve reliability.
  • Tests
    • Added backend unit/E2E and frontend tests covering propose/confirm, validation, persistence, grouping, and error handling.

ADR-0016 D8 の残課題「表示名・粒度の畳み込み(agent 提案→人間確定)」を D11 として
実装。package/infra の生スキル名を agent が読みやすい表示名・グループへ提案し、人間が
確認・編集して確定・永続化する。確定値は Layer 1-2(機械・洗い替え対象)から切り離した
独立テーブル github_skill_display_decisions に安定 identity で保存し、再連携の洗い替えに
耐える。serve 時の解決順は「確定値 > 機械 display_name(Linguist) > canonical」。
backend:
- 新テーブル + migration 0048 / GitHubSkillDisplayDecisionRepository
- services/agent/skill_display(proposer + output_schema)+ prompt。agent は提案のみ・
メンバーは動的 enum で捏造排除・リトライ1回・課金は既存契約流用(ADR-0010/0012/0013)
- エンドポイント: POST propose(billed)/ PUT confirm(authz)/ GET skills(decision join)
- 課金後処理 record_usage_after_llm を billing service へ集約(agent router と共用)
- 提案は language を除外し package/infra に限定、キャップ 50(入力・enum 肥大の抑制)
web:
- ダッシュボードにスキル一覧 + 提案レビュー/確定 UI(SkillDisplaySection)
- 決定論ロジックは utils/skillDisplay に切り出し TDD(red→green)
- ダークモード対応のためテーマトークンで配色
ADR-0016 に D11 を追補・改訂履歴・索引整合を更新。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation backend バックエンド web フロントエンド (web) test テスト追加・修正 agent DevForge Agent feature 新機能 labels Jul 14, 2026
@coderabbitai

coderabbitaiBot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a9287b86-3247-4a9c-a211-b835a1a00754

📥 Commits

Reviewing files that changed from the base of the PR and between 8ae526b and b7a0840.

📒 Files selected for processing (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/hooks/useGitHubSkills.ts

📝 Walkthrough

Walkthrough

This PR adds a human-in-the-loop GitHub skill display workflow. It persists confirmed names and groups, generates constrained LLM proposals, exposes proposal and confirmation APIs, and adds frontend state management, review UI, tests, and ADR-0016 documentation.

Changes

GitHub skill display decisions

Layer / File(s)Summary
Decision persistence and API contracts
backend/alembic_migrations/..., backend/app/models/..., backend/app/repositories/..., backend/app/schemas/...
Adds the decision table, ORM model, identity-keyed upsert repository, enriched skill responses, and proposal/confirmation schemas.
LLM proposal engine and usage handling
backend/app/services/agent/skill_display/*, backend/app/prompts/agent_skill_display.md, backend/app/services/billing/credit_service.py, backend/tests/test_skill_display_service.py
Adds constrained structured LLM proposals, validation, retry handling, usage propagation, and unit tests.
Backend proposal and confirmation endpoints
backend/app/routers/github_link/*, backend/tests/test_skill_display_api.py
Adds proposal and confirmation endpoints with filtering, credit checks, identity validation, persistence, refreshed responses, and API coverage.
Frontend API, grouping, and state management
web/src/api/*, web/src/utils/skillDisplay.*, web/src/hooks/useGitHubSkills.*
Adds generated contracts, API wrappers, display grouping utilities, proposal editing, confirmation state, and unit tests.
Skills display UI and acceptance coverage
web/src/components/github-link/*, web/src/constants/messages.ts, web/e2e/github-link.spec.ts, docs/adr/0016-github-skill-inference.md
Adds the dashboard review interface, styling, UI messages, browser coverage, and D11 ADR updates.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
participant User
participant SkillDisplaySection
participant useGitHubSkills
participant GitHubLinkAPI
participant LLMProposer
User->>SkillDisplaySection: Request display-name proposal
SkillDisplaySection->>useGitHubSkills: propose()
useGitHubSkills->>GitHubLinkAPI: POST display-names/propose
GitHubLinkAPI->>LLMProposer: Generate constrained groups
LLMProposer-->>GitHubLinkAPI: Proposed groups
GitHubLinkAPI-->>useGitHubSkills: Proposal response
User->>SkillDisplaySection: Edit and confirm groups
SkillDisplaySection->>useGitHubSkills: confirm()
useGitHubSkills->>GitHubLinkAPI: PUT display-decisions
GitHubLinkAPI-->>useGitHubSkills: Enriched skills
useGitHubSkills-->>SkillDisplaySection: Render confirmed names
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 75.81% which is insufficient. The required threshold is 80.00%.Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check nameStatusExplanation
Description Check✅ PassedCheck skipped - CodeRabbit’s high-level summary is enabled.
Title check✅ PassedThe title clearly describes the main change: an agent-assisted, human-confirmed skill display-name folding flow for ADR-0016 D11.
Linked Issues check✅ PassedThe PR implements the human-in-the-loop proposal, human confirmation, Layer 3 persistence, and display reflection requested by #476.
Out of Scope Changes check✅ PassedI don't see unrelated code changes; the additions support the skill display proposal/confirmation flow and its tests.
✨ 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 feat/skill-display-name-hitl

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.

@coderabbitaicoderabbitaiBot 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.

Actionable comments posted: 5

🧹 Nitpick comments (1)
backend/app/repositories/skill.py (1)

119-130: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Deduplicate inputs to prevent potential Unique Constraint violations.

If decisions contains duplicate items for an identity that is not yet in the database, self.db.add() will be called multiple times for the same key. This will result in an IntegrityError (500 Internal Server Error) when self.db.commit() is executed.

Consider deduplicating the input array by its identity key to gracefully handle any duplicates from the client.

♻️ Proposed refactor to deduplicate items
 existing = {
(d.kind, d.ecosystem, d.canonical_name): d for d in self.get_for_user()
}
- for item in decisions:++ unique_decisions = {+ (d.kind, d.ecosystem, d.canonical_name): d for d in decisions+ }.values()++ for item in unique_decisions:
key = (item.kind, item.ecosystem, item.canonical_name)
current = existing.get(key)
if current is not None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/app/repositories/skill.py` around lines 119 - 130, Deduplicate
decisions by the (kind, ecosystem, canonical_name) identity before the
add/commit flow in the repository method containing the existing map and
decisions loop. Ensure only one item per key is processed, while preserving
updates for existing records and preventing duplicate new records from reaching
self.db.add().
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/app/routers/github_link/endpoints.py`:
- Around line 237-272: Cap the number of entries accepted by
SkillDisplayConfirmRequest.decisions using the project’s established
request-validation convention, such as a max_items constraint. Choose the
intended maximum batch size and ensure oversized requests are rejected before
confirm_skill_display_decisions performs identity validation or calls
upsert_many.
- Around line 237-257: Update confirm_skill_display_decisions to reject
decisions whose kind is SKILL_KIND_LANGUAGE, matching the exclusion used by the
propose-side flow. Apply this validation before persisting any decisions, while
preserving the existing identity validation and allowing only package/infra
skills.
In `@web/src/components/github-link/SkillDisplaySection.tsx`:
- Around line 58-69: Disable the Propose button whenever an existing proposal is
open, in addition to the current proposing and confirming guards, so propose()
cannot replace a proposal while confirm() is still using it. Update the matching
button guard in the alternate section around the referenced lines as well,
preserving the existing loading labels and click behavior.
- Around line 83-89: Update the proposal name input in SkillDisplaySection so
each field’s aria-label uniquely identifies its skill group, incorporating the
row’s group-specific display name or another available unique identifier while
retaining the existing label context. Ensure assistive technology can
distinguish inputs across all proposal rows.
In `@web/src/hooks/useGitHubSkills.ts`:
- Around line 39-49: Clear the existing error state at the start of the reload
callback in useGitHubSkills, before calling getGitHubSkills. Preserve the
current success, failure, loading, and cleanup behavior so a successful retry
leaves error null while failures still record the converted error.
---
Nitpick comments:
In `@backend/app/repositories/skill.py`:
- Around line 119-130: Deduplicate decisions by the (kind, ecosystem,
canonical_name) identity before the add/commit flow in the repository method
containing the existing map and decisions loop. Ensure only one item per key is
processed, while preserving updates for existing records and preventing
duplicate new records from reaching self.db.add().
🪄 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 Plus

Run ID: 948bf89e-19b3-4bab-9440-df3b1289e7c7

📥 Commits

Reviewing files that changed from the base of the PR and between 8d7cdc6 and 8ae526b.

📒 Files selected for processing (30)
  • backend/alembic_migrations/versions/0048_add_github_skill_display_decision.py
  • backend/app/messages.json
  • backend/app/models/__init__.py
  • backend/app/models/skill.py
  • backend/app/prompts/agent_skill_display.md
  • backend/app/repositories/skill.py
  • backend/app/routers/agent.py
  • backend/app/routers/github_link/_responses.py
  • backend/app/routers/github_link/endpoints.py
  • backend/app/schemas/github_skill.py
  • backend/app/services/agent/skill_display/__init__.py
  • backend/app/services/agent/skill_display/output_schema.py
  • backend/app/services/agent/skill_display/proposer.py
  • backend/app/services/billing/credit_service.py
  • backend/tests/test_skill_display_api.py
  • backend/tests/test_skill_display_service.py
  • docs/adr/0016-github-skill-inference.md
  • web/e2e/github-link.spec.ts
  • web/src/api/generated.ts
  • web/src/api/githubLink.ts
  • web/src/api/paths.ts
  • web/src/api/types.ts
  • web/src/components/github-link/GitHubLinkDashboard.tsx
  • web/src/components/github-link/SkillDisplaySection.module.css
  • web/src/components/github-link/SkillDisplaySection.tsx
  • web/src/constants/messages.ts
  • web/src/hooks/useGitHubSkills.test.ts
  • web/src/hooks/useGitHubSkills.ts
  • web/src/utils/skillDisplay.test.ts
  • web/src/utils/skillDisplay.ts

Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadbackend/app/routers/github_link/endpoints.py
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/components/github-link/SkillDisplaySection.tsx
Comment threadweb/src/hooks/useGitHubSkills.ts
- レビュー中(提案表示中)は再提案ボタンを無効化し、確定待ちの提案を取りこぼさない
- 提案レビューの表示名入力に対象スキルを含めた aria-label を付与(各行を支援技術で区別可能に)
- useGitHubSkills.reload の成功時に error をクリア(前回の失敗表示が残らないように)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@yusuke0610
yusuke0610 merged commit d985b47 into mainJul 14, 2026
23 checks passed
@yusuke0610
yusuke0610 deleted the feat/skill-display-name-hitl branch July 20, 2026 12:25
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentDevForge AgentbackendバックエンドdocumentationImprovements or additions to documentationfeature新機能testテスト追加・修正webフロントエンド (web)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(agent): スキル表示名の human-in-the-loop 畳み込み確定フロー(ADR-0016 D8)

1 participant

@yusuke0610