Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .agents/wisdom/process.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
- Free tier has rate limits (35 min cooldown). After hitting the limit, sleep and retry.
- CodeRabbit finds things the pre-push self-review misses (security lens, async assertion gaps). Do not skip it.

## CodeRabbit SUCCESS with no review output requires verification

When the CodeRabbit status check shows SUCCESS but no review summary or inline
comments are posted, do not assume the review ran or that it was rate-limited.
Check whether the latest reviewable commit was covered and whether the result
was rate-limited, unavailable, or skipped incrementally.

**Always**: After triggering `@coderabbitai review`, wait 2-3 minutes, then:
1. Check PR comments for a review summary
2. Fetch inline comments: `gh api --paginate repos/<owner>/<repo>/pulls/<num>/comments`
3. If no valid review evidence exists, report the review as unavailable and
require an explicit human decision before proceeding

## Pre-merge three-step gate

From `docs/engineering-workflow.md`:
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ dist/
.DS_Store
.pi-subagents/
.scratch/
video
.playwright-cli/
.playwright-mcp/
.worktrees/
17 changes: 10 additions & 7 deletions examples/interactive-decision-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,19 @@ Then open **http://localhost:3000** (or whatever port your server uses) in a bro
| `cars.read` | ✅ | ✅ | ✅ |
| `cars.create` | ✅ | ✅ | ✅ |
| `cars.update` | ✅ | ✅ | ❌ `no-grant` |
| `cars.delete` | ✅ | ✅ | ❌ `matching-denial` |
| `cars.delete` | ✅ | ✅ (schedule) | ❌ `matching-denial` |
| `manage-policy` | ✅ | ❌ `no-grant` | ❌ `no-grant` |
| `reports.read` | ✅ (schedule) | ❌ `no-grant` | ❌ `no-grant` |

## How the schedule works

Super Admin can enable/disable the schedule restriction on `reports.read` and
adjust the UTC business-hours window. A controllable evaluation clock advances
or rewinds time — within hours the permission allows, outside it returns
`outside-schedule`. Admin and Support cannot modify these settings.
Super Admin can enable/disable the schedule restriction on Admin's `cars.delete`
and adjust the UTC business-hours window. A controllable evaluation clock
advances or rewinds time — within hours the permission allows, outside it
returns `outside-schedule`. Admin and Support can see the schedule status but
cannot modify the settings.

The schedule rule is enforced through the real Mizan `manage-policy` decision —
non-Super Admin users who attempt to change the schedule will be blocked by the
authorization engine, not just by disabled UI controls.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated

## Stack

Expand Down
66 changes: 29 additions & 37 deletions examples/interactive-decision-demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,7 @@ <h3 class="policy-block-title">Deny overrides</h3>
</label>
</div>
<div class="policy-block">
<h3 class="policy-block-title">Temporal schedule</h3>
<p class="schedule-note">Hypothetical: <code>reports.read</code> evaluated against a configurable schedule.</p>
<label class="policy-toggle" data-permission="schedule">
<input type="checkbox" id="toggle-schedule" checked />
<span class="toggle-label">Enforce schedule on <code>reports.read</code></span>
</label>
<div class="schedule-editor">
<div class="hour-input-group">
<label class="hour-label" for="schedule-start-h">Start (UTC)</label>
<div class="hour-field">
<input type="number" id="schedule-start-h" class="hour-input" min="0" max="23" value="9" aria-label="Start hour" />
<span class="hour-sep">:</span>
<input type="number" id="schedule-start-m" class="hour-input minute" min="0" max="59" value="0" step="15" aria-label="Start minute" />
</div>
</div>
<div class="hour-input-group">
<label class="hour-label" for="schedule-end-h">End (UTC)</label>
<div class="hour-field">
<input type="number" id="schedule-end-h" class="hour-input" min="0" max="23" value="17" aria-label="End hour" />
<span class="hour-sep">:</span>
<input type="number" id="schedule-end-m" class="hour-input minute" min="0" max="59" value="0" step="15" aria-label="End minute" />
</div>
</div>
</div>
<div class="clock-controls">
<span class="clock-label">Evaluation clock</span>
<div class="clock-row">
<span id="clock-display" class="clock-time" aria-live="polite">—</span>
<div class="clock-buttons">
<button id="clock-dec" class="clock-btn" type="button">−1h</button>
<button id="clock-inc" class="clock-btn" type="button">+1h</button>
<button id="clock-reset" class="clock-btn" type="button">reset</button>
</div>
</div>
<div id="schedule-result" class="schedule-result" aria-live="polite">—</div>
</div>
<p class="schedule-note">Schedule controls are in the toolbar above, visible to all principals. Only Super Admin can modify them. Controls Admin's <code>cars.delete</code> permission.</p>
</div>
</div>

Expand Down Expand Up @@ -131,7 +96,34 @@ <h3 class="policy-block-title">Temporal schedule</h3>
</div>
</section>

<!-- Decision strip (main column, directly below controls) -->
<!-- Schedule bar (main column, directly below controls) -->
<div id="schedule-bar" class="schedule-bar">
<label class="schedule-toggle-compact" title="Enable/disable schedule enforcement">
<input type="checkbox" id="toggle-schedule" checked />
<span>Schedule <code>cars.delete</code></span>
</label>
<div class="schedule-hours">
<input type="number" id="schedule-start-h" class="hour-input" min="0" max="23" value="9" aria-label="Start hour" />
<span class="hour-sep">:</span>
<input type="number" id="schedule-start-m" class="hour-input minute" min="0" max="59" value="0" step="15" aria-label="Start minute" />
<span class="schedule-dash">—</span>
<input type="number" id="schedule-end-h" class="hour-input" min="0" max="23" value="17" aria-label="End hour" />
<span class="hour-sep">:</span>
<input type="number" id="schedule-end-m" class="hour-input minute" min="0" max="59" value="0" step="15" aria-label="End minute" />
<span class="schedule-tz">UTC</span>
</div>
<div class="schedule-clock">
<span id="clock-display" class="clock-time" aria-live="polite">—</span>
<div class="clock-buttons">
<button id="clock-dec" class="clock-btn" type="button" title="Decrease clock by 1 hour">−1h</button>
<button id="clock-inc" class="clock-btn" type="button" title="Increase clock by 1 hour">+1h</button>
<button id="clock-reset" class="clock-btn" type="button" title="Reset clock to initial time">reset</button>
</div>
</div>
<div id="schedule-result" class="schedule-result" aria-live="polite">—</div>
</div>

<!-- Decision strip (main column, directly below schedule bar) -->
<div id="current-decision" class="decision-strip" aria-live="polite" role="status" hidden>
<span class="decision-actor-label"></span>
<span class="decision-verb"></span>
Expand Down
Loading
Loading