Skip to content

feat(conditions): flag/role guards on edges (G5) — Gate 3, Phase 3 done#24

Merged
officialCodeWork merged 1 commit into
developmentfrom
build/phase-3/step-3.5-flag-role
Jul 14, 2026
Merged

feat(conditions): flag/role guards on edges (G5) — Gate 3, Phase 3 done#24
officialCodeWork merged 1 commit into
developmentfrom
build/phase-3/step-3.5-flag-role

Conversation

@officialCodeWork

Copy link
Copy Markdown
Owner

Step 3.5 — Flag / role conditions (closes Gate 3)

Failure modes G5/B5. Feature-flag and role guards now annotate the edges — and the journey steps — they gate.

  • A renders/handles edge enclosed by a flag call (isEnabled/useFlag/useFeature/…, extensible via the new featureFlags scan option) or a role check (role ===, hasRole, hasPermission, can(, …) carries an EdgeCondition{kind:"flag"|"role"}.
  • Ternary else-branches are negated; a flag hook result used as a bare boolean (const beta = useFlag("beta")) is resolved back to its flag call.
  • journeys() surfaces the guard on the step it gates, so a path reads:
    ▸ /billing • onClick [flag isEnabled("new-billing")] → /billing/new

Bonus fix

Inline-handler id collision: two inline-arrow on* handlers in one component collapsed into a single event node (dropping the second's condition + effect). Inline handlers are now disambiguated by line — caught precisely because the two guards in the g5 fixture would otherwise merge.

Eval

New conditions golden check + fixture g5-feature-flag (flag-gated navigation, role-gated fetch, flag-gated child render). No schema change — EdgeCondition already existed.

Verification

  • 92 parser + 29 core tests pass; the inline-handler fix caused zero regressions.
  • pnpm eval: green, precision/recall 1.000. Gate 3 passes → Phase 3 (journey graph) complete.

Next: Phase 4 (matching engine).

🤖 Generated with Claude Code

…Gate 3

Feature-flag and role guards now annotate the edges (and journey steps) they
gate (TRACKER step 3.5, failure modes G5/B5):

- A renders/handles edge enclosed by a flag call (isEnabled/useFlag/useFeature/…,
  extensible via scan option `featureFlags`) or a role check (role===, hasRole,
  hasPermission, can(), …) carries an EdgeCondition{kind:"flag"|"role"}.
- Ternary else-branches are negated; a flag hook result used as a bare boolean
  (`const beta = useFlag("beta")`) is resolved back to its flag call.
- journeys() surfaces the handles-edge guard on the step it gates, so a path
  reads "… onClick [flag isEnabled("new-billing")] → navigate /billing/new".

Also fix an inline-handler id collision: two inline-arrow on* handlers in one
component collapsed to a single event node (dropping the second's condition and
effect). Inline handlers are now disambiguated by line.

Eval: new `conditions` golden check + fixture g5-feature-flag (flag-gated
navigation, role-gated fetch, flag-gated child render). 92 parser + 29 core
tests pass; eval green (precision/recall 1.000). **Gate 3 passes — Phase 3 done.**

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@officialCodeWork
officialCodeWork merged commit 2ee3a54 into development Jul 14, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants