Skip to content

docs(openspec): scope seeding the hydra flow definitions — the stated blocker is not real - #111

Merged
rubenvdlinde merged 1 commit into
developmentfrom
docs/seed-hydra-flows-proposal
Aug 2, 2026
Merged

docs(openspec): scope seeding the hydra flow definitions — the stated blocker is not real#111
rubenvdlinde merged 1 commit into
developmentfrom
docs/seed-hydra-flows-proposal

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

The blocker this was framed around does not exist

The task was framed as:

Seeding needs a user session. IRepairStep runs with NO session, so the obvious "seed on install" fails closed with User 'Anonymous' does not have permission to 'create' objects in schema 'Agent flow'. This already breaks the fresh-install path for EVERY app that seeds via IRepairStep.

That is not what the code does, and not what the live instance shows.

ObjectService::saveObject() takes _rbac and _multitenancy flags, and hermiq already uses them from a repair step — lib/Repair/SeedHydraTriageFlow.php:

$objectService->saveObject(
    object: $this->flowObject(),
    register: self::REGISTER_SLUG,
    schema: self::FLOW_SCHEMA,
    _rbac: false,
    _multitenancy: false
);

That step is registered in appinfo/info.xml (both <pre-migration> and <post-migration>), it seeds an agentflow object into the same register and schema the ten hydra flows would land in, and its result is on the live instance:

name          | _owner      | enabled
Hydra Triage  | __system__  | f

Owner __system__, not Anonymous. Thirteen hermiq repair steps use this pattern. Object seeding from an IRepairStep is a solved, shipped problem here.

So why is this still a proposal?

Not because of the session. Because of a question that should not be answered unilaterally inside a bug-fix PR: the ten definitions live in the hydra repo, which is not a Nextcloud app and has no repair steps. The seeder must be a hermiq artifact, so something has to own the copy.

  • (a) Vendor the JSON into hermiq — simple, matches how hermiq_register.json ships. Cost: two copies, nothing keeps them in step.
  • (b) Fetch from hydra at install time — no duplication, but a network call in a repair step must then fail soft, and a soft-failing seeder is exactly the silent-success shape this batch of work exists to remove.
  • (c) Ship as an OpenRegister configuration, imported via ConfigurationService::importFromApp() like ImportFlowRegister does. Most idiomatic; costed first. Known trap: a non-forced importFromApp advances the version without applying.

Recommendation (c), falling back to (a).

Everything else is already settled

The proposal records what the seeder must do, taken from the existing pattern rather than invented: disabled with no owner (a trigger fires with no acting user, and every one of these flows writes to the forge), idempotent by name, preflighted per flow against or#2254, and — unlike SeedHydraTriageFlow, which catches every Throwable into a warning so a failed seed still reports a clean install — it must not swallow a real failure.

Live state

Two of ten present, both hand-seeded (_owner = admin, disabled): hydra-file-findings, hydra-record-stage. All three node-owning apps are enabled, so every step type in all ten resolves.

⚠️ But four of the ten would now be refused at save by or#2254's config-dialect check (hydra-analyze-verdicts, hydra-record-stage, hydra-retry-escalate, hydra-lock-reaper). Fixing those definitions is a prerequisite for seeding them, and is listed as such.

… blocker is not real

The change was framed around IRepairStep having no user session, so seeding
"fails closed with User 'Anonymous' does not have permission to 'create'".

That is not what the code does. ObjectService::saveObject() takes `_rbac` and
`_multitenancy` flags, and hermiq already uses them from a repair step:
lib/Repair/SeedHydraTriageFlow.php seeds an agentflow object into the same
register and schema with `_rbac: false, _multitenancy: false`. It is
registered in appinfo/info.xml and its result is on the live instance right
now — `Hydra Triage`, owner `__system__`, disabled. Thirteen hermiq repair
steps use this pattern.

So the work is unblocked and ordinary. What it is NOT is decided: the ten
definitions live in the hydra repo, which is not a Nextcloud app, so the
seeder must be a hermiq artifact and something has to own the copy. Vendoring
duplicates them with nothing keeping the copies in step; fetching at install
time puts a network call in a repair step that would then have to fail soft,
which is the silent-success shape this batch exists to remove. Shipping them
as an OpenRegister configuration is the most idiomatic and is costed first.

That is an architectural choice, not a bug fix, so it is written up rather
than made unilaterally. Everything the seeder must do is already settled by
the existing pattern and recorded here.
@rubenvdlinde
rubenvdlinde requested a review from Rem-Dam as a code owner August 2, 2026 08:05
@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/hermiq @ 7ffe26b

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 117/117
npm ✅ 657/657
PHPUnit
Newman
Playwright ⏭️

Coverage: 85.3% (93/109 statements)


Quality workflow — 2026-08-02 08:09 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit 3283d90 into development Aug 2, 2026
33 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