Skip to content

spec: process templates become policies on the OpenRegister decision lifecycle (gate 23) - #1284

Merged
rubenvdlinde merged 3 commits into
developmentfrom
spec/process-templates-as-lifecycle-policies
Sep 11, 2026
Merged

spec: process templates become policies on the OpenRegister decision lifecycle (gate 23)#1284
rubenvdlinde merged 3 commits into
developmentfrom
spec/process-templates-as-lifecycle-policies

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What

An OpenSpec change (proposal, design, two spec deltas, tasks) for the migration
that clears hydra gate 23 (or-abstraction, rule 5
consume-or-workflow-engine-fleet-wide) honestly. No code changes here.

A process template stops drawing its own state machine. The Decision lifecycle
keeps one map, the x-openregister-lifecycle block OpenRegister runs, and a
template becomes a policy on that map: per action who may take the step and
what must be true first, template-wide quorum and decide-without-vote.
StateMachineValidator is deleted because templates no longer have graphs, not
renamed.

Why

Gate 23 turns blocking on 2026-10-03 00:00 UTC and its only decidiq finding
is lib/Service/StateMachineValidator.php. Measured in this clone, forced block
mode: or_abstraction_findings=1 app_id=decidiq mode=BLOCK, exit 1.

Reading the code behind the finding turned up four claims the code does not
keep, all written up in the proposal:

  1. Two transition maps (DecisionTransitionGuard::TRANSITIONS and the schema
    annotation), pinned together by a test, neither derived from the other.
  2. Template graphs are decorative. Only chair-only edges and two flags are read.
  3. Three of the four guard tokens (quorum_met, all_amendments_resolved,
    legal_review_complete) are validated and enforced nowhere, while the schema
    says "Guard tokens enforced before this transition".
  4. The register's own note: "KNOWN GAP: a raw write straight to OpenRegister's
    object API bypasses that gate, exactly as it already bypasses the chair-only
    and quorum gates."

Verification

  • openspec validate process-templates-as-lifecycle-policies --strict: valid.
  • OpenRegister mechanics read at development 4bd08be and measured live on
    :8080 against the decision schema (id 978): a raw PUT from draft to
    enacted answers 422 lifecycle-invalid-transition, draft to
    proposed answers 200. So OpenRegister already enforces the graph on the
    object API, and a requires guard runs in the same listener
    (LifecycleValidationListener.php:227).
  • Gate 23 in forced block mode on this branch is unchanged from development
    (1 finding): this PR ships no code. The design states the measurement the
    first code PR must show.
  • Local vendor/bin/hydra-gates at full scope: 2 failures, both
    ajv not resolvable in this checkout (gate-22, gate-53), an environment
    miss, not a finding about this diff. CI installs node deps and is the
    authority.

Open product questions

The design carries two, each with a recommendation, and the guard PR waits for
answers:

  • Q1 which domain policy applies. DecisionContextResolver::resolveDomain()
    reads decision.domain and meeting.domain; no schema declares either, so
    every decision resolves to the permissive operations policy today.
    GovernanceBody.domain holds the real value and nobody reads it for this.
  • Q2 where chair-only binds. On every write, which stops a secretary
    opening or closing the vote in a chair-only body, or on decidiq's decision
    endpoint only, which keeps today's bypass.

Refs #1277

🤖 Generated with Claude Code

… decision lifecycle

Proposes the migration that clears hydra gate 23 (or-abstraction, rule 5)
honestly: StateMachineValidator is deleted because templates stop having
graphs, not renamed. The Decision lifecycle keeps one map, the
x-openregister-lifecycle block OpenRegister runs, and one OpenRegister
lifecycle guard enforces the body's policy on every write, including a
write straight to the object API.

Design records the OpenRegister guard mechanics as measured, the repair
step for stored template graphs, the honest guard vocabulary, the fate of
DecisionTransitionGuard, and two open product questions (Q1 domain
resolution, Q2 chair-only scope) that gate the guard PR.

Refs #1277
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/decidiq @ 5835c7e

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-nav-ceiling
test-l10n
format
check-l10n-js
check-schema-l10n
composer ✅ 104/104
npm ✅ 545/545
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-09-11 07:55 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 9497688 into development Sep 11, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant