Skip to content

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
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;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
[codex] Add Workflows Engineer dashboard role by michaelmwu · Pull Request #298 · 508-dev/508-workflows · GitHub
Skip to content

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

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

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

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

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

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

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

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

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@michaelmwu
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' [codex] Add Workflows Engineer dashboard role by michaelmwu · Pull Request #298 · 508-dev/508-workflows · GitHub
Skip to content

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

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

[codex] Add Workflows Engineer dashboard role - #298

Merged
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role
May 20, 2026
Merged

[codex] Add Workflows Engineer dashboard role#298
michaelmwu merged 1 commit into
mainfrom
michaelmwu/workflows-engineer-role

Conversation

@michaelmwu

@michaelmwumichaelmwu commented May 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add the Discord Workflows Engineer role as a Steering Committee peer for normal dashboard writes.
  • Grant Workflows Engineers admin read access for jobs/audit plus dry-run permissions for job reruns and people/project sync writes.
  • Surface dry-run responses in the dashboard UI, rebuild dashboard assets, and update role/docs/tests.

Validation

  • bun run check
  • bun run build
  • ./scripts/lint.sh
  • ./scripts/test.sh (1492 passed, 20 skipped)

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced "Workflows Engineer" role with Steering Committee-level write permissions and admin read access
    • Added dry-run functionality for project sync, people sync, and job rerun operations with visual warning notifications
    • Enhanced dashboard UI with warning indicators for dry-run mode operations
  • Documentation

    • Updated API and architecture documentation to clarify Workflows Engineer role capabilities and dashboard access permissions
  • Tests

    • Expanded test coverage for Workflows Engineer role and dry-run operation flows

Review Change Stack

@coderabbitai

coderabbitaiBot commented May 20, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@michaelmwu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 6 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7b9e6099-efe2-4936-8f9e-5ab5a6ab2b91

📥 Commits

Reviewing files that changed from the base of the PR and between c3b377f and b612bba.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
📝 Walkthrough

Walkthrough

This PR introduces the Workflows Engineer Discord role as a Steering Committee peer with dry-run access for admin-only sync and rerun operations. Changes span role definition and hierarchy refactoring, dashboard permission computation, dry-run authorization helpers wired into endpoints, frontend UI updates to handle dry-run responses, cross-service integration, and comprehensive test coverage.

Changes

Workflows Engineer Role with Dry-Run Access

Layer / File(s)Summary
Role Definition and Permission Constants
apps/api/src/five08/backend/auth.py, ARCHITECTURE.md, ENVIRONMENT.md
New WORKFLOWS_ENGINEER_ROLE constant and _ROLE_LEVELS mapping define the role's hierarchy position. Three dry-run permission constants and two permission sets (DASHBOARD_WORKFLOWS_ENGINEER_PERMISSIONS and DASHBOARD_WORKFLOWS_ENGINEER_SENSITIVE_PERMISSIONS) grant Steering Committee write parity plus admin read and dry-run access. Documentation clarifies that Workflows Engineer is not an admin role but a Steering Committee peer with restricted capabilities.
Role Hierarchy System Refactor
apps/api/src/five08/backend/auth.py, apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
Hierarchy evaluation switches from list-based to mapping-based approach via _ROLE_LEVELS. Both has_role_with_hierarchy and get_user_hierarchy_level now use the mapping to compute user levels; Workflows Engineer is placed at level 1 (peer to Steering Committee). Role decorator documentation updated to reflect peer-level access grants.
Dashboard Permission Computation and Session Derivation
apps/api/src/five08/backend/api.py, apps/api/src/five08/backend/auth.py, apps/api/README.md
dashboard_permissions_for_roles returns Workflows Engineer permission set when role is detected. Session permission derivation conditionally removes or grants workflows-engineer-sensitive permissions based on Discord role checks via _discord_workflows_engineer_can_use_sensitive_dashboard helper. Base session permissions apply the same logic. API documentation clarifies Workflows Engineer permissions for Discord-backed sessions.
Dry-Run Authorization and Endpoint Helpers
apps/api/src/five08/backend/api.py
New _dashboard_write_session_or_dry_run helper gates write vs. dry-run access by checking both normal and dry-run permissions. _rerun_job_dry_run validates job and returns would-enqueue description without persisting. Handlers for sync_projects, rerun_job, and sync_people use these helpers to short-circuit with dry-run responses when only dry-run permission is granted.
Frontend Dashboard: UI and Dry-Run Response Handling
apps/admin_dashboard/src/main.tsx
Toast system gains "warning" tone with amber styling. New canDryRun and canUse helpers enable UI actions based on either normal or dry-run permissions. syncProjects, rerunJob, and syncPeople handle richer API responses (dry_run, would_enqueue, optional job_id) and emit warning toasts for dry runs vs. ok toasts for queued jobs. View permission props (canSync, canWrite) updated to use canUse instead of can.
Cross-Service Role Integration
apps/discord_bot/src/five08/discord_bot/cogs/agent.py, apps/discord_bot/src/five08/discord_bot/cogs/crm.py, packages/shared/src/five08/agent/policy.py, packages/shared/src/five08/job_match.py
Agent capability detection now recognizes "workflows engineer" as engineer-equivalent. Workflows Engineer added to CRM protected roles list. Policy scope computation treats "workflows engineer" the same as "engineer" for scope selection. Job-matching auto-suggestion excludes Workflows Engineer from role suggestions.
Test Coverage and Dashboard Build Artifacts
tests/unit/test_backend_api.py, tests/unit/test_role_decorators.py, apps/api/src/five08/backend/static/dashboard/...
New tests verify /dashboard/api/me returns correct Workflows Engineer permissions, /dashboard/api/jobs/{job_id}/rerun enters dry-run mode, and /dashboard/api/sync/* endpoints return dry-run responses without persisting. Role decorator tests extend hierarchy fixture and validate Workflows Engineer behavior. Dashboard Tailwind CSS and Vite manifest rebuilt with updated asset hashes.

Sequence Diagram(s)

sequenceDiagram
participant Discord User
participant SessionInit as Session<br/>Initialization
participant PermLogic as Permission<br/>Logic
participant Endpoint as Dashboard<br/>Endpoint
participant DryRunHelper
participant Frontend
Discord User->>SessionInit: Workflows Engineer role
SessionInit->>PermLogic: has_workflows_engineer_role check
PermLogic->>PermLogic: Conditionally grant dry-run permissions
PermLogic->>Endpoint: Return scoped session
Frontend->>Endpoint: POST sync/rerun with canUse permission
Endpoint->>DryRunHelper: Check dry-run vs. write access
alt has write permission
DryRunHelper->>Endpoint: Return can_write=True
Endpoint->>Endpoint: Enqueue job
Endpoint->>Frontend: Return ok toast
else has only dry-run permission
DryRunHelper->>Endpoint: Return dry_run=True
Endpoint->>Frontend: Return would_enqueue description + warning toast
end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • 508-dev/508-workflows#288: Both PRs refactor dashboard permission computation in apps/api/src/five08/backend/api.py by adding conditional "sensitive" permission granting based on Discord role checks—this PR for Workflows Engineer dry-run/write behavior, the retrieved PR for trusted Admin sensitive permissions.

Poem

🐰 A new role hops into view,
Workflows Engineer, Steering's peer so true,
With dry runs to preview without write's full might,
Permission hierarchies restructured just right,
The dashboard toasts warnings in amber delight!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check nameStatusExplanationResolution
Docstring Coverage⚠️ WarningDocstring coverage is 40.38% 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 and specifically identifies the main change: introducing a new 'Workflows Engineer' dashboard role.
Linked Issues check✅ PassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes check✅ PassedCheck skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch michaelmwu/workflows-engineer-role

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 and usage tips.

@chatgpt-codex-connectorchatgpt-codex-connectorBot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:e6b3d9df25

ℹ️ About Codex in GitHub

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

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

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

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

Comment threadapps/admin_dashboard/src/main.tsx

CopilotAI 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.

Pull request overview

This PR introduces a new Discord Workflows Engineer role that behaves as a Steering Committee peer for normal dashboard writes, while granting additional admin-like read access (jobs/audit) and dry-run access for sensitive write operations (job reruns and people/project syncs). It also updates the dashboard UI to surface dry-run responses and refreshes documentation/assets/tests accordingly.

Changes:

  • Add Workflows Engineer to role/permission evaluation across the API backend, Discord bot utilities, and shared policy code.
  • Introduce dry-run permissions and handlers for dashboard write endpoints (rerun/sync), and display dry-run feedback in the dashboard UI.
  • Update tests and documentation, and rebuild dashboard static assets/manifest.

Reviewed changes

Copilot reviewed 16 out of 19 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
tests/unit/test_role_decorators.pyAdds hierarchy tests ensuring Workflows Engineer is a Steering Committee peer but not Admin.
tests/unit/test_backend_api.pyAdds permission and dry-run behavior tests for Workflows Engineer dashboard sessions.
packages/shared/src/five08/job_match.pyPrevents auto-suggest/apply for the new role.
packages/shared/src/five08/agent/policy.pyTreats workflows engineer as an engineer role for agent scopes.
ENVIRONMENT.mdDocuments the new role’s intended permission model.
ARCHITECTURE.mdDocuments dashboard permission behavior including dry-run semantics.
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.pyUpdates Discord command role hierarchy logic to include Workflows Engineer.
apps/discord_bot/src/five08/discord_bot/cogs/crm.pyProtects Workflows Engineer from automatic role apply operations.
apps/discord_bot/src/five08/discord_bot/cogs/agent.pyAllows workflows engineer to see engineer-level agent capabilities.
apps/api/src/five08/backend/static/dashboard/index.htmlUpdates static asset references to rebuilt dashboard bundles.
apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.cssAdds rebuilt CSS bundle.
apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.cssRemoves prior CSS bundle.
apps/api/src/five08/backend/static/dashboard/.vite/manifest.jsonUpdates manifest to point at rebuilt asset filenames.
apps/api/src/five08/backend/auth.pyAdds Workflows Engineer permission sets, role checks, and sensitive-permission handling.
apps/api/src/five08/backend/api.pyAdds dry-run session helper + dry-run implementations for rerun/sync endpoints.
apps/api/README.mdDocuments new role behavior and the dry-run exception model.
apps/admin_dashboard/src/main.tsxAdds dry-run UI handling (warning toast, enabling certain actions via *:dry_run).
Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment threadapps/api/src/five08/backend/auth.py
Comment threadapps/discord_bot/src/five08/discord_bot/utils/role_decorators.py Outdated
Comment threadapps/api/src/five08/backend/api.py Outdated
Comment threadapps/admin_dashboard/src/main.tsx

@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: 1

🧹 Nitpick comments (3)
apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py (1)

121-127: 💤 Low value

role_levels is duplicated in two functions.

The role_levels mapping is defined identically in both check_user_roles_with_hierarchy and get_user_hierarchy_level. Consider extracting it to a module-level constant for consistency and easier maintenance, similar to _ROLE_LEVELS in auth.py.

♻️ Proposed refactor
+# Role hierarchy levels for access control+ROLE_LEVELS = {+ "Member": 0,+ "Steering Committee": 1,+ "Workflows Engineer": 1,+ "Admin": 2,+ "Owner": 3,+}++
def check_user_roles_with_hierarchy(
user_roles: List[discord.Role], required_roles: List[str]
) -> bool:
...
- role_levels = {- "Member": 0,- "Steering Committee": 1,- "Workflows Engineer": 1,- "Admin": 2,- "Owner": 3,- }
...
- if role_name in role_levels:- user_highest_level = max(user_highest_level, role_levels[role_name])+ if role_name in ROLE_LEVELS:+ user_highest_level = max(user_highest_level, ROLE_LEVELS[role_name])

Apply similar changes to get_user_hierarchy_level.

Also applies to: 160-166

🤖 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 `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py` around
lines 121 - 127, The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
apps/api/src/five08/backend/auth.py (1)

28-36: 💤 Low value

Remove unused ROLE_HIERARCHY tuple.

The ROLE_HIERARCHY tuple at line 28 is not referenced anywhere in the codebase and has been superseded by the _ROLE_LEVELS mapping for hierarchy evaluation. Removing it will eliminate unnecessary duplication and clarify that _ROLE_LEVELS is the authoritative hierarchy source.

🤖 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 `@apps/api/src/five08/backend/auth.py` around lines 28 - 36, Remove the unused
ROLE_HIERARCHY tuple declaration and keep _ROLE_LEVELS as the single source of
truth for role hierarchy; delete the line defining ROLE_HIERARCHY and ensure any
references are not present elsewhere (verify by searching for ROLE_HIERARCHY),
leaving WORKFLOWS_ENGINEER_ROLE and _ROLE_LEVELS intact and run tests/lint to
confirm no breakage.
apps/admin_dashboard/src/main.tsx (1)

1529-1543: 💤 Low value

Consider extracting the dry-run response type.

The response type { job_id?: string; dry_run?: boolean; would_enqueue?: { job_type?: string } } is duplicated across syncProjects, rerunJob, and syncPeople. Extracting to a shared type alias would improve maintainability.

typeDryRunResponse={job_id?: stringdry_run?: booleanwould_enqueue?: {job_type?: string}}
🤖 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 `@apps/admin_dashboard/src/main.tsx` around lines 1529 - 1543, Extract the
duplicated response shape into a shared type alias (e.g., DryRunResponse) and
replace the inline generic object type used in requestJson calls; update the
places that use the same shape (notably the requestJson call inside the function
handling "syncPeople" where payload is declared, and the similar usages in
syncProjects and rerunJob) to requestJson<DryRunResponse>(...) so they all
reference the new DryRunResponse type; add the type near related request helpers
or a shared types file and update imports if necessary.
🤖 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 `@apps/discord_bot/src/five08/discord_bot/cogs/crm.py`:
- Around line 79-81: The user-facing blocked-role message is hardcoded and now
out-of-sync with the protection set; instead build that message dynamically from
the _DISCORD_ROLES_PROTECTED_FROM_APPLY frozenset so it always reflects current
protected roles. Locate where the "blocked-role" / blocked-role message is
constructed (the user-facing string shown when apply is rejected) and replace
the hardcoded list with a formatted join of
sorted(_DISCORD_ROLES_PROTECTED_FROM_APPLY) (e.g., comma-separated with final
separator) to preserve deterministic ordering and readable punctuation; ensure
you reference _DISCORD_ROLES_PROTECTED_FROM_APPLY and keep the rest of the error
wording intact.
---
Nitpick comments:
In `@apps/admin_dashboard/src/main.tsx`:
- Around line 1529-1543: Extract the duplicated response shape into a shared
type alias (e.g., DryRunResponse) and replace the inline generic object type
used in requestJson calls; update the places that use the same shape (notably
the requestJson call inside the function handling "syncPeople" where payload is
declared, and the similar usages in syncProjects and rerunJob) to
requestJson<DryRunResponse>(...) so they all reference the new DryRunResponse
type; add the type near related request helpers or a shared types file and
update imports if necessary.
In `@apps/api/src/five08/backend/auth.py`:
- Around line 28-36: Remove the unused ROLE_HIERARCHY tuple declaration and keep
_ROLE_LEVELS as the single source of truth for role hierarchy; delete the line
defining ROLE_HIERARCHY and ensure any references are not present elsewhere
(verify by searching for ROLE_HIERARCHY), leaving WORKFLOWS_ENGINEER_ROLE and
_ROLE_LEVELS intact and run tests/lint to confirm no breakage.
In `@apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py`:
- Around line 121-127: The duplicate role_levels mapping used in
check_user_roles_with_hierarchy and get_user_hierarchy_level should be extracted
to a single module-level constant (e.g., _ROLE_LEVELS) so both functions
reference the same source of truth; create the constant at top of the file, move
the mapping there, and replace the local role_levels references in
check_user_roles_with_hierarchy and get_user_hierarchy_level with the new
_ROLE_LEVELS name to ensure consistency and easier maintenance.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c92b7a16-b14c-47d5-88d4-d36d2ce4799a

📥 Commits

Reviewing files that changed from the base of the PR and between deac4bb and c3b377f.

📒 Files selected for processing (19)
  • ARCHITECTURE.md
  • ENVIRONMENT.md
  • apps/admin_dashboard/src/main.tsx
  • apps/api/README.md
  • apps/api/src/five08/backend/api.py
  • apps/api/src/five08/backend/auth.py
  • apps/api/src/five08/backend/static/dashboard/.vite/manifest.json
  • apps/api/src/five08/backend/static/dashboard/assets/index-B8EWkBmI.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-CPTdpcwK.js
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css
  • apps/api/src/five08/backend/static/dashboard/index.html
  • apps/discord_bot/src/five08/discord_bot/cogs/agent.py
  • apps/discord_bot/src/five08/discord_bot/cogs/crm.py
  • apps/discord_bot/src/five08/discord_bot/utils/role_decorators.py
  • packages/shared/src/five08/agent/policy.py
  • packages/shared/src/five08/job_match.py
  • tests/unit/test_backend_api.py
  • tests/unit/test_role_decorators.py
💤 Files with no reviewable changes (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-D9GwxYhO.css

Comment threadapps/discord_bot/src/five08/discord_bot/cogs/crm.py

CopilotAI 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.

Pull request overview

Copilot reviewed 16 out of 19 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • apps/api/src/five08/backend/static/dashboard/assets/index-DW09PDM3.css: Language not supported
Comments suppressed due to low confidence (1)

tests/unit/test_backend_api.py:5169

  • These new Workflows Engineer dry-run endpoint tests also run under the default test environment, which bypasses the production SSO gating. Add a production-environment variant (e.g., monkeypatch.setattr(api.settings, "environment", "production")) to ensure Workflows Engineer still receives dry-run access when id_token is empty in production.
def test_dashboard_rerun_job_workflows_engineer_is_dry_run(
client: TestClient,
) -> None:
session = api.AuthSession(
subject="workflows-1",
email="workflows@508.dev",
display_name="Workflows Engineer",
groups=["Workflows Engineer"],
is_admin=False,
id_token="",
expires_at=4_102_444_800,
actor_provider=api.ActorProvider.DISCORD.value,
)
source_job = Mock(
id="job-old-1",
type="sync_people_from_crm_job",
max_attempts=8,
payload={"args": [], "kwargs": {"reason": "manual"}},
)
with (
patch(
"five08.backend.api._current_session",
new_callable=AsyncMock,
return_value=("session-1", session),
),
patch("five08.backend.api.get_job", return_value=source_job),
patch("five08.backend.api._rerun_job", new_callable=AsyncMock) as mock_rerun,
patch("five08.backend.api.insert_audit_event") as mock_insert,
):
response = client.post("/dashboard/api/jobs/job-old-1/rerun")

Comment threadtests/unit/test_backend_api.py
@michaelmwu
michaelmwuforce-pushed the michaelmwu/workflows-engineer-role branch from 6e8c23e to b612bbaCompareMay 20, 2026 09:27
@michaelmwu
michaelmwu merged commit c57fd62 into mainMay 20, 2026
7 checks passed
@michaelmwu
michaelmwu deleted the michaelmwu/workflows-engineer-role branch May 20, 2026 15:45
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@michaelmwu