Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
338 commits
Select commit Hold shift + click to select a range
7efacd0
feat(relations): walk the relations, prune out loud, and say what a l…
rubenvdlinde Sep 18, 2026
28d9505
feat(rbac): an aggregate over a property obeys that property's read r…
rubenvdlinde Sep 18, 2026
62e17f8
feat(timers): a term can roll off a day nobody works, and say what mo…
rubenvdlinde Sep 18, 2026
e27d54b
feat(flows): running a flow is decided per flow, where the run path r…
rubenvdlinde Sep 18, 2026
f74abd8
docs(openspec): point task 9.2's note at the PR that actually closed …
rubenvdlinde Sep 18, 2026
ce7018b
feat(objects): a reference picker reads its options from the same rul…
rubenvdlinde Sep 18, 2026
298827c
feat(email): thread a reply by its headers, and refuse to guess (#3914)
rubenvdlinde Sep 18, 2026
878de2c
feat(bpmn): the mapping both directions read, and the report that can…
rubenvdlinde Sep 18, 2026
018ea8a
docs(spec): write the three notification rules the engine now holds i…
rubenvdlinde Sep 18, 2026
cb5f7f0
feat(survey): a survey is an object, and its promises are refusals ra…
rubenvdlinde Sep 18, 2026
25f9deb
feat(timers): a working calendar declares the hours its clock runs (#…
rubenvdlinde Sep 18, 2026
1d0c110
feat(rbac): a property's existence is described only to a caller who …
rubenvdlinde Sep 18, 2026
de4079b
feat(bpmn): the serialisers, the round trip and the two endpoints (#3…
rubenvdlinde Sep 18, 2026
e4d5f3b
test(bpmn): hold the boundary, and never export an edge to nowhere (#…
rubenvdlinde Sep 18, 2026
fe31545
The anonymisation act refuses rather than guesses, and can be finishe…
rubenvdlinde Sep 18, 2026
2f7bc67
feat(schemas): a property may declare where its values come from (#3952)
rubenvdlinde Sep 18, 2026
bad4c6a
fix(survey): import the surveys register, and gate every descriptor t…
rubenvdlinde Sep 18, 2026
f53247b
feat(views): a saved view can say when its count crosses a line (#3953)
rubenvdlinde Sep 18, 2026
d7bf906
feat(leaves): a leaf that cannot render refuses to register (#3954)
rubenvdlinde Sep 18, 2026
9767f9b
fix(leaves): report a missing leaf bundle, do not refuse the leaf (#3…
rubenvdlinde Sep 18, 2026
58e829a
feat(leaves): a leaf declares how it loads, and a claim can be checke…
rubenvdlinde Sep 18, 2026
9ec5267
feat(timers): index the predicate the calendar recompute actually rea…
rubenvdlinde Sep 18, 2026
c918837
docs(relations): close 2.1 and 2.2 against pipelinq's schema (#3959)
rubenvdlinde Sep 18, 2026
1ce6843
feat(system-context): a system write declares itself, and the declara…
rubenvdlinde Sep 18, 2026
97c0998
Rescue: the audit trail names the token, the copy and the setting cha…
rubenvdlinde Sep 18, 2026
7ba9fea
feat(notifications): a rule that reaches nobody says so (#3961)
rubenvdlinde Sep 18, 2026
1a895e0
docs(rbac): an empty rule list means one thing in each layer, and bot…
rubenvdlinde Sep 18, 2026
852f51d
docs(notifications): record that the reach report has no caller, and …
rubenvdlinde Sep 18, 2026
0452148
feat(hardening): the statement a user accepts, and the fresh sign-in …
rubenvdlinde Sep 18, 2026
a0b84a8
A page opens without a session only when the app declares it public (…
rubenvdlinde Sep 18, 2026
16fce31
feat(rbac): a cross-register read stops at the tenant edge (#3966)
rubenvdlinde Sep 18, 2026
c169f24
feat(relations): a link hands over the fields it declares, and nothin…
rubenvdlinde Sep 18, 2026
ce162a0
feat(operations): one console for what the instance is doing, and wha…
rubenvdlinde Sep 18, 2026
5acc09f
feat(export): exporting is a right of its own, with its own field set…
rubenvdlinde Sep 18, 2026
9d0f8d3
merge development into parity/round2
rubenvdlinde Sep 18, 2026
b7d0ff0
fix(quality): the two eslint errors this branch introduced
rubenvdlinde Sep 18, 2026
14f931e
docs(openspec): an export is a file with a life, not a write and a sh…
rubenvdlinde Sep 18, 2026
fc9830b
fix(quality): the phpcs errors these 95 commits introduced
rubenvdlinde Sep 18, 2026
b868e1b
Merge remote-tracking branch 'origin/parity/round2' into parity/round2
rubenvdlinde Sep 18, 2026
78ea820
fix(quality): the three failing unit tests, the unresolvable spec tar…
rubenvdlinde Sep 18, 2026
11c0d44
fix(quality): spec coverage for the 128 methods this branch added, an…
rubenvdlinde Sep 18, 2026
8807642
fix(quality): no else clause, and the one endpoint that does have a c…
rubenvdlinde Sep 18, 2026
f119fc4
fix(quality): the analysers' NEW findings, and three real bugs among …
rubenvdlinde Sep 18, 2026
c5ae79b
fix(timers): read the boolean roll before normalising the rest
rubenvdlinde Sep 18, 2026
a609f46
feat(openspec): additional object access control is openregister's, a…
rubenvdlinde Sep 19, 2026
63ddfd5
feat(timers): the opening hours, the working days and the holidays ar…
rubenvdlinde Sep 19, 2026
8082165
feat(bpmn): vendor the OMG schema set and validate both directions ag…
rubenvdlinde Sep 19, 2026
2571402
fix(rbac): the hierarchy and the department matrix actually reach the…
rubenvdlinde Sep 19, 2026
e5804ce
fix(validation): a property that declares only a $ref no longer break…
rubenvdlinde Sep 19, 2026
7a81910
docs(quality): document the 35 parameters and functions this programm…
rubenvdlinde Sep 19, 2026
1318e59
Merge remote-tracking branch 'origin/development' into parity/round2
rubenvdlinde Sep 19, 2026
13e50c6
fix(routes): the thirteen routes Nextcloud was overwriting get their …
rubenvdlinde Sep 19, 2026
5d19faf
fix(views): the field guard is called, and the four analyser findings…
rubenvdlinde Sep 19, 2026
41be6c1
docs(spec): the four BpmnSchemaValidator methods gate 16 reports
rubenvdlinde Sep 19, 2026
51ec1b5
Merge pull request #3979 from ConductionNL/parity/round2
rubenvdlinde Sep 19, 2026
fb00bba
style(e2e): prettier on the two spec files the merge left unformatted
rubenvdlinde Sep 19, 2026
de1a595
Merge pull request #3982 from ConductionNL/fix/round2-postmerge-reds
rubenvdlinde Sep 19, 2026
acf46da
fix(locks): a write stops claiming the lock it just released
rubenvdlinde Sep 19, 2026
2ae6926
docs: PR body for the lock release fix
rubenvdlinde Sep 19, 2026
a6adcc2
chore: keep the PR body out of the tree, it belongs to the PR not the…
rubenvdlinde Sep 19, 2026
0b6049e
chore(sync): carry beta back into development
github-actions[bot] Sep 19, 2026
2d77722
Merge pull request #3986 from ConductionNL/sync/beta-to-development-2…
rubenvdlinde Sep 19, 2026
f84db0e
fix(gates): the operand check gets a call site, and six endpoints get…
rubenvdlinde Sep 19, 2026
91f5d29
chore(l10n): the 111 strings the round-2 merge added, in all 36 locales
rubenvdlinde Sep 19, 2026
4924dbe
fix(locks): a lock with no duration expires the instant it is taken
rubenvdlinde Sep 19, 2026
6c02541
Merge pull request #3988 from ConductionNL/fix/hydra-gates-6-and-25
rubenvdlinde Sep 19, 2026
f648a9f
Merge pull request #3989 from ConductionNL/chore/l10n-the-111-strings…
rubenvdlinde Sep 19, 2026
2822af9
Merge pull request #3984 from ConductionNL/fix/lock-release-truth-in-…
rubenvdlinde Sep 19, 2026
271ee65
chore(phpmd): clear the 24 StaticAccess findings
rubenvdlinde Sep 19, 2026
bfe090f
Merge pull request #3993 from ConductionNL/chore/phpmd-staticaccess-s…
rubenvdlinde Sep 19, 2026
18fc26d
refactor(phpmd): decompose six over-complex methods
rubenvdlinde Sep 19, 2026
74330b1
refactor(phpmd): decompose six more over-complex methods
rubenvdlinde Sep 19, 2026
d0df6cd
refactor(phpmd): decompose four more over-complex methods
rubenvdlinde Sep 19, 2026
a2c39fe
refactor(phpmd): decompose six more over-complex methods
rubenvdlinde Sep 19, 2026
1bfd913
refactor(phpmd): decompose six more over-complex methods
rubenvdlinde Sep 19, 2026
21b20bb
fix(flow-tasks): authorize create against the object the task is about
rubenvdlinde Sep 19, 2026
ea0ffa8
refactor(phpmd): decompose the last four over-complex methods
rubenvdlinde Sep 19, 2026
097895b
style(phpcs): capitalise an inline comment
rubenvdlinde Sep 19, 2026
3841a03
fix(search): resolve a register or schema reference on the read path,…
rubenvdlinde Sep 19, 2026
0996c0d
Merge pull request #3996 from ConductionNL/fix/read-path-resolves-reg…
rubenvdlinde Sep 19, 2026
492450b
Merge pull request #3995 from ConductionNL/chore/phpmd-complexity-sweep
rubenvdlinde Sep 19, 2026
17aef4e
fix(bpmn): validate against the vendored schema under Nextcloud's ent…
rubenvdlinde Sep 19, 2026
203376e
test(bpmn): assert the vendored schema imports resolve under the null…
rubenvdlinde Sep 19, 2026
68f93ac
style(psalm): capture the restore call's result so it is not read as …
rubenvdlinde Sep 19, 2026
85b27e2
test(bpmn): put the previous entity resolver back instead of clearing it
rubenvdlinde Sep 19, 2026
23c4f18
docs(spec): the vendored schema set must be readable where the host b…
rubenvdlinde Sep 19, 2026
5c3b7c2
Name the four classes the guard's tests execute in @uses
rubenvdlinde Sep 19, 2026
aae502f
Merge pull request #3998 from ConductionNL/fix/flow-task-create-is-au…
rubenvdlinde Sep 19, 2026
f34b8c6
Merge pull request #3999 from ConductionNL/fix/bpmn-schema-validation…
rubenvdlinde Sep 19, 2026
87d306b
Put Nextcloud's entity loader back instead of clearing it
rubenvdlinde Sep 19, 2026
2cfb7c6
Merge pull request #4001 from ConductionNL/fix/entity-loader-restore
rubenvdlinde Sep 19, 2026
a9d0a22
refactor(notifications): the recipient audience is an enum, not a boo…
rubenvdlinde Sep 19, 2026
3a7e9b1
refactor(views): the caller's reach is one object, read in one place
rubenvdlinde Sep 19, 2026
adad66f
refactor(flow): migration, the test run and the run guard each get th…
rubenvdlinde Sep 19, 2026
a86ca17
refactor(rbac): four responsibilities leave the three classes that ha…
rubenvdlinde Sep 19, 2026
18cc882
refactor(rbac,flow,views): wire the extracted classes into their callers
rubenvdlinde Sep 19, 2026
cd2881d
refactor(flow): the SLA declaration, the working-day roll and the cal…
rubenvdlinde Sep 19, 2026
82e6a24
refactor(bpmn): a strict import is its own call, and the diagram layo…
rubenvdlinde Sep 19, 2026
f76aa08
refactor: the register document loader, the bulk-job guards and objec…
rubenvdlinde Sep 19, 2026
2e6298c
refactor(graphql): the aggregation types move out, and two entities s…
rubenvdlinde Sep 19, 2026
bd7fe34
refactor(operations): consistency and maintenance leave the console c…
rubenvdlinde Sep 19, 2026
5c6bbdc
refactor: six classes that had grown a second job hand it over
rubenvdlinde Sep 19, 2026
fe8df28
fix(quality): the moved code keeps its own house in order
rubenvdlinde Sep 19, 2026
1a95723
Merge remote-tracking branch 'origin/development' into chore/phpmd-sw…
rubenvdlinde Sep 19, 2026
4514c99
chore(bpmn): name why the vendored loader keeps a parameter it does n…
rubenvdlinde Sep 19, 2026
86a5a55
fix(gates): the hydra gates on this diff, run locally before pushing
rubenvdlinde Sep 20, 2026
8fafbc5
chore(bulkjob): one spec tag on assertUndoCeiling, not two
rubenvdlinde Sep 20, 2026
6e4d946
Merge pull request #4003 from ConductionNL/chore/phpmd-sweep-round2
rubenvdlinde Sep 20, 2026
c4c0bdb
Merge remote-tracking branch 'origin/development' into feat/woo-578-a…
WilcoLouwerse Sep 21, 2026
a57f6f3
Merge remote-tracking branch 'origin/development' into fix/woo-579-re…
WilcoLouwerse Sep 21, 2026
7f5ffa0
test(file-text): drop the ADR-005 assertion that could not fail
WilcoLouwerse Sep 21, 2026
2dc6402
Merge remote-tracking branch 'origin/development' into fix/woo-577-ch…
WilcoLouwerse Sep 21, 2026
ed846b3
fix(i18n): project translatable properties on the magic-mapper list p…
SudoThijn Sep 21, 2026
b9651a5
test(i18n): give the write-only leak test a real TranslationHandler
SudoThijn Sep 21, 2026
3603987
Merge pull request #4011 from ConductionNL/fix/translatable-projectio…
SudoThijn Sep 21, 2026
4cad4aa
chore(reuse): 17 verbatim MDI glyphs in PHP, and the sweep that misse…
WilcoLouwerse Sep 21, 2026
ecb6a84
chore(reuse): the Nationaal Archief examples get the block their side…
WilcoLouwerse Sep 21, 2026
24acbfc
docs(contributing): the REUSE gate blocks now, so write it down somew…
WilcoLouwerse Sep 21, 2026
c522c38
chore(reuse): record that the DiWoo/TOOI exports were checked, and wh…
WilcoLouwerse Sep 21, 2026
75ae4f3
Merge remote-tracking branch 'origin/development' into feat/woo-578-a…
WilcoLouwerse Sep 21, 2026
c4ec90f
Merge commit '3603987d0e' into fix/woo-577-chunk-arm-paging
WilcoLouwerse Sep 21, 2026
e50c6b2
fix(schema): a default of false, 0 or "" survives getSchemaObject()
SudoThijn Sep 21, 2026
184582d
Merge commit '3603987d0e' into fix/woo-576-fs-context-text-extraction
WilcoLouwerse Sep 21, 2026
5e2aa65
Merge pull request #3857 from ConductionNL/fix/woo-579-reuse-compliance
WilcoLouwerse Sep 21, 2026
2481899
Merge remote-tracking branch 'origin/development' into woo576-devmerge
WilcoLouwerse Sep 21, 2026
5518503
Merge remote-tracking branch 'origin/development' into woo578-devmerge
WilcoLouwerse Sep 21, 2026
00a66af
Merge remote-tracking branch 'origin/development' into woo577-devmerge
WilcoLouwerse Sep 21, 2026
fea3298
fix(schema): keep '' stripped, and let a zero floor through
SudoThijn Sep 21, 2026
0279978
Merge branch 'development' into fix/falsy-schema-defaults-survive-get…
SudoThijn Sep 21, 2026
e48961e
fix(schema): a zero exclusive bound is a value too
SudoThijn Sep 21, 2026
02d9dd1
Merge pull request #4012 from ConductionNL/fix/falsy-schema-defaults-…
SudoThijn Sep 21, 2026
472ba28
fix(text-extraction): address the four open review threads on #3778
WilcoLouwerse Sep 22, 2026
67c2de4
style(cron): drop the else branch phpmd flags on the truncated-walk log
WilcoLouwerse Sep 22, 2026
2386388
chore(deps): move nextcloud-vue back to the 2.x line
rubenvdlinde Sep 22, 2026
48f1c75
fix(rbac): the anonymous scope also suspends the grant it cannot be n…
WilcoLouwerse Sep 22, 2026
c4ffd87
test(unit): a whole test directory has been silent since two refactor…
WilcoLouwerse Sep 22, 2026
038b39f
Merge pull request #4014 from ConductionNL/fix/orphan-unit-test-names…
WilcoLouwerse Sep 22, 2026
40f56d2
build(deps): this repo sets the fleet's Dexie, so freeze it explicitl…
rubenvdlinde Sep 22, 2026
735498c
feat(audit): the audit trail reads within a caller's own scope
rubenvdlinde Sep 22, 2026
8388b38
chore(openspec): archive audit-trail-readable-scope and sync its delta
rubenvdlinde Sep 22, 2026
92be1b6
test(audit): assert the scoped route is reachable and declared before…
rubenvdlinde Sep 22, 2026
14c029c
Merge pull request #3778 from ConductionNL/fix/woo-576-fs-context-tex…
WilcoLouwerse Sep 22, 2026
939a053
Merge pull request #3856 from ConductionNL/fix/woo-577-chunk-arm-paging
WilcoLouwerse Sep 22, 2026
c7eff10
Merge pull request #3855 from ConductionNL/feat/woo-578-anonymous-eva…
WilcoLouwerse Sep 22, 2026
11766c7
refactor(audit): split the scan so the lister clears phpmd on its own…
rubenvdlinde Sep 22, 2026
4ef34c9
Merge development into feat/audit-trail-readable-scope
rubenvdlinde Sep 22, 2026
52fb1ca
Merge pull request #4018 from ConductionNL/feat/audit-trail-readable-…
rubenvdlinde Sep 22, 2026
af16c72
feat(export): a produced export is a run, with an expiry and a count
rubenvdlinde Sep 22, 2026
ab535d7
fix(tests): give the two controller tests the constructor arguments t…
rubenvdlinde Sep 22, 2026
1554c99
Merge pull request #4021 from ConductionNL/feat/export-runs-have-a-life
rubenvdlinde Sep 22, 2026
e0d852b
Merge pull request #4013 from ConductionNL/chore/nextcloud-vue-back-t…
rubenvdlinde Sep 23, 2026
e21c760
chore(deps-dev): bump @babel/plugin-transform-typescript (#4032)
dependabot[bot] Sep 25, 2026
c42143a
chore(deps): bump phpoffice/phpspreadsheet from 5.9.0 to 5.10.0 (#4027)
dependabot[bot] Sep 25, 2026
cfacc39
chore(deps): bump zod from 4.5.4 to 4.6.5 (#4026)
dependabot[bot] Sep 25, 2026
315d209
chore(deps): bump vue from 3.5.42 to 3.5.43 (#4024)
dependabot[bot] Sep 25, 2026
8575ea4
chore(deps-dev): bump @types/node from 26.4.1 to 26.6.2 (#4023)
dependabot[bot] Sep 25, 2026
226f874
chore(deps): bump dompurify from 3.4.14 to 3.4.15 (#3792)
dependabot[bot] Sep 25, 2026
898bc7c
wip(parity): openregister capability matrix, systems, areas and rows,…
rubenvdlinde Sep 25, 2026
68c97f3
wip(parity): records and files rated from the code
rubenvdlinde Sep 25, 2026
b3328b5
wip(parity): access, history and retention rated from the code
rubenvdlinde Sep 25, 2026
0442865
wip(parity): modelling and exchange rated from the code
rubenvdlinde Sep 25, 2026
15979f9
wip(parity): api, search and ai rated from the code
rubenvdlinde Sep 25, 2026
efdfd0e
feat(parity): openregister capability matrix, 167 rows across 12 area…
rubenvdlinde Sep 25, 2026
fa26b38
fix(parity): phrase the runtime-type row as the user sees it
rubenvdlinde Sep 25, 2026
eaf781a
Merge pull request #4040 from ConductionNL/feat/parity-capability-matrix
rubenvdlinde Sep 25, 2026
86a2fb8
chore(deps): bump dexie from 4.4.5 to 4.4.6 (#3788)
dependabot[bot] Sep 26, 2026
0034196
wip(parity): re-rate five competitor columns from source at release t…
rubenvdlinde Sep 26, 2026
5b62078
feat(parity): add 30 demand-signal rows rated in all six columns, own…
rubenvdlinde Sep 26, 2026
7367d6d
Merge pull request #4056 from ConductionNL/feat/parity-wave5-competit…
rubenvdlinde Sep 26, 2026
c89e881
fix(parity): corrections round 5, readVersion and schema enum
rubenvdlinde Sep 26, 2026
6f6b187
Merge pull request #4062 from ConductionNL/parity/corrections-5
rubenvdlinde Sep 26, 2026
55c5ba6
fix(files): apply the file type and size limit set in the schema prop…
rubenvdlinde Sep 27, 2026
bb263ff
Merge pull request #4065 from ConductionNL/fix/4058-file-config-limits
rubenvdlinde Sep 27, 2026
22966bd
fix(audit): record changes to Open Register's own settings on the aud…
rubenvdlinde Sep 27, 2026
1162f35
feat(consent): reusable, append-only consent evidence envelope (#4049)
rubenvdlinde Sep 27, 2026
d53c023
feat(talk): let a linked room accept an external participant by email…
rubenvdlinde Sep 27, 2026
701caad
Merge pull request #4067 from ConductionNL/fix/4060-own-settings-audit
rubenvdlinde Sep 27, 2026
0ef78c6
fix(oas): document PATCH on object paths and name the NLGov method ru…
rubenvdlinde Sep 27, 2026
0f21375
Merge pull request #4069 from ConductionNL/fix/4059-oas-patch
rubenvdlinde Sep 27, 2026
e920d4e
feat(access-links): make and manage access links on the object page, …
rubenvdlinde Sep 27, 2026
71527ce
Merge pull request #4071 from ConductionNL/fix/4061-access-link-screens
rubenvdlinde Sep 27, 2026
d611a36
fix(deps): move zbateson/mail-mime-parser to 3.0.8 for two high advis…
rubenvdlinde Sep 27, 2026
0dbd6b9
fix(import): a schema component without a slug is imported under its key
rubenvdlinde Sep 27, 2026
0ca409e
chore(deps): move @conduction/nextcloud-vue to 2.57.1 (Dexie loads on…
rubenvdlinde Sep 27, 2026
c0d9ebb
feat(text-extraction): read PowerPoint decks into structured slides (…
rubenvdlinde Sep 27, 2026
84352ba
feat(store): publish one object to the registry through the store pla…
rubenvdlinde Sep 27, 2026
c53dd06
feat(import): stamp app imports with an import job id so an app can r…
rubenvdlinde Sep 27, 2026
4fee776
chore(deps): relax the dexie pin now that nextcloud-vue loads it lazi…
rubenvdlinde Sep 27, 2026
ae898b0
docs(openspec): parity gap decisions and 12 modelling and records cha…
rubenvdlinde Sep 27, 2026
86e106f
fix(rbac): every canonical verb of the permission catalogue is a vali…
rubenvdlinde Sep 27, 2026
c67a79e
Merge pull request #4091 from ConductionNL/fix/catalogue-verbs-are-va…
rubenvdlinde Sep 27, 2026
9c37822
Merge pull request #4084 from ConductionNL/fix/schema-slug-defaults-t…
rubenvdlinde Sep 27, 2026
4ae2212
docs(openspec): 11 api, history, operate, retention, exchange, ai and…
rubenvdlinde Sep 27, 2026
555af72
docs(openspec): 10 detection, tasks, webhooks, restore, notification,…
rubenvdlinde Sep 27, 2026
d6bb0ba
docs(parity): corrections round 8, 2 rows re-read against their issue…
rubenvdlinde Sep 28, 2026
5cda2f0
docs(openspec): owner-moves decision pass (34 decisions, 19 changes) …
rubenvdlinde Sep 28, 2026
9ce171e
feat(text-extraction): read Word documents into headings, sections an…
rubenvdlinde Sep 28, 2026
ecaba04
fix(files): the first upload into a register creates its folder witho…
rubenvdlinde Sep 28, 2026
37b6cda
fix(credentials): start an OAuth2 connection, and answer each refusal…
SudoThijn Sep 28, 2026
71f19b9
fix(credentials): keep the client secret out of the log, and a failed…
SudoThijn Sep 28, 2026
d6fea63
feat(credentials): tell a person why a connect start was refused
SudoThijn Sep 28, 2026
b1080c9
fix(credentials): leave nothing behind when a connection start fails
SudoThijn Sep 28, 2026
2b9fdea
feat(flow): send-email reaches external addresses under an allowlist …
rubenvdlinde Sep 28, 2026
bd97666
fix(trash): scope the trash listing, count and destruction record to …
rubenvdlinde Sep 28, 2026
e0ecbbf
fix(tags): refuse a tag change without the update right on the object…
rubenvdlinde Sep 28, 2026
3d2f74f
fix(credentials): rotate a secret before saving, and pin withdraw's o…
SudoThijn Sep 28, 2026
8d87385
fix(search): scope semantic and hybrid file search to files the calle…
rubenvdlinde Sep 28, 2026
1f46120
fix(actions): seed flow.read and add seeded actions an existing matri…
rubenvdlinde Sep 28, 2026
5e641d9
fix(audit): integrity and file audit rows take their expiry from the …
rubenvdlinde Sep 28, 2026
8b046a5
fix(schemas): keep configuration.exportable and serve it back (#4131)
rubenvdlinde Sep 28, 2026
20762ec
fix(openspec): fold delta headers in seven main specs back into Requi…
rubenvdlinde Sep 28, 2026
1c45ce2
fix(detection): find a Dutch BSN by the elfproef and report it as SSN…
rubenvdlinde Sep 28, 2026
51e8b7d
fix(detection): extractFile takes the entity filter, anonymiq gets it…
rubenvdlinde Sep 28, 2026
cecd8b6
fix(revert): a revert meets the freeze, the schema and the audit trai…
rubenvdlinde Sep 28, 2026
6016e10
fix(files): GET /api/files/{fileId}/text returns the extracted text (…
rubenvdlinde Sep 28, 2026
a0e59d9
fix(registers): a deleted register's folder goes with it (#4143)
rubenvdlinde Sep 28, 2026
b156216
feat(files): registers an app imports get their Files folder at impor…
rubenvdlinde Sep 28, 2026
13910a5
fix(timeline): a mention notification links to the object, and quoted…
rubenvdlinde Sep 28, 2026
2d91913
fix(import): classify, version and log the schema changes an import m…
rubenvdlinde Sep 28, 2026
4c83321
fix(settings): record LLM, file and search backend settings changes o…
rubenvdlinde Sep 28, 2026
599db3f
fix(rbac): ask the create question about the incoming data so a match…
rubenvdlinde Sep 28, 2026
c73343f
fix(rbac): refuse unknown match operators at save and deny on the lis…
rubenvdlinde Sep 28, 2026
ccd0134
fix(export): an export keeps the property filters of the list it came…
rubenvdlinde Sep 28, 2026
ac7296b
fix(schemas): the schema tool and the source merge classify their cha…
rubenvdlinde Sep 28, 2026
910471d
test: declare @uses for the 592 classes that 797 unit tests execute w…
rubenvdlinde Sep 28, 2026
47b6979
fix(credentials): refuse an out-of-bounds update before rotating, and…
SudoThijn Sep 29, 2026
1a8d1c6
Merge remote-tracking branch 'origin/development' into fix/oauth2-sta…
SudoThijn Sep 29, 2026
ff0532e
test(credentials): pin the allowedApps bound to characters, not bytes
SudoThijn Sep 29, 2026
5eb46b6
fix(tests): implement registerSystemReportSection in RecordingRegistr…
SudoThijn Sep 29, 2026
4abd834
Merge pull request #4119 from ConductionNL/fix/oauth2-start-status-codes
SudoThijn Sep 29, 2026
ed9f155
fix(revert): a revert works again, by slug too, and a frozen object a…
rubenvdlinde Sep 29, 2026
2788101
fix(append-only): an insert with a caller-chosen uuid is an insert, n…
rubenvdlinde Sep 29, 2026
0ea8332
fix(schemas): a malformed authorization rule is refused with 400 nami…
rubenvdlinde Sep 29, 2026
63daa72
fix(import): a configuration import keeps the schema version it bumpe…
rubenvdlinde Sep 29, 2026
cf05d9d
fix(rbac): a full save keeps a field the writer was not allowed to re…
rubenvdlinde Sep 29, 2026
b876628
feat(export): another app can render the rows it fetched as a PDF (#4…
rubenvdlinde Sep 29, 2026
25e5384
feat(rules): a condition can read an allowlisted value source through…
rubenvdlinde Sep 29, 2026
442120a
feat(portal): a party whose portal task passes its deadline gets an o…
rubenvdlinde Sep 29, 2026
d3684bf
docs(parity): decide the 87 open openregister rows and specify the mi…
rubenvdlinde Sep 29, 2026
a4d1e9b
fix(rbac): accept a property's authorization.audit flag as a control …
rubenvdlinde Sep 29, 2026
f8fef91
feat(archival): each matter holds an object with its own legal hold (…
rubenvdlinde Sep 29, 2026
7683bff
fix(delete): deleteObject's own lookups honour the caller's _rbac and…
rubenvdlinde Sep 29, 2026
a5832f2
feat(approval): an amount can need every approval tier at or below it…
rubenvdlinde Sep 29, 2026
e010e24
fix(schemas): an unacknowledged breaking change from an agent or a so…
rubenvdlinde Sep 29, 2026
5d341f3
feat(extraction): another app can hand in the text it read from a sca…
rubenvdlinde Sep 30, 2026
574a0f3
fix(encryption): an encrypted property gets a TEXT column, and only a…
rubenvdlinde Sep 30, 2026
fd14b27
feat(audit): an app counts and lists the audit actions it writes unde…
rubenvdlinde Sep 30, 2026
7ce6a99
feat(views): a saved view can be shared with a group, and the share i…
rubenvdlinde Sep 30, 2026
792794c
fix(rbac): a boolean in a match rule is bound as a boolean, not as th…
rubenvdlinde Sep 30, 2026
8e001f4
feat(views): a group member with write access can edit a shared view …
rubenvdlinde Sep 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
Empty file removed --help
Empty file.
8 changes: 8 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ bin/console text eol=lf
*.ico binary
*.png binary

# 🔴 THE VENDORED OMG BPMN SCHEMA SET IS BYTE-PINNED, SO GIT MUST NOT TOUCH IT.
# The five files ship with CRLF endings exactly as omg.org serves them, and
# `* text=auto eol=lf` above would rewrite every line on checkout: the files on
# disk would then no longer hash to the SHA-256 sums recorded in
# schema/PROVENANCE.md, which is both a failing provenance test and, more to
# the point, a modified copy of a specification we said we had not modified.
lib/Service/Flow/Bpmn/schema/*.xsd -text

.github export-ignore
.travis.yml export-ignore
LICENSE export-ignore
Expand Down
62 changes: 58 additions & 4 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,61 @@ jobs:
# mis-parse it. Path is relative to `server/`, which the step cd's into.
playwright-seed-command: bash apps/openregister/tests/e2e/ci/seed.sh
enable-coverage-guard: true
# ── Licensing ────────────────────────────────────────────────────────
# REUSE findings fail the build. The shared workflow defaults this OFF
# because most fleet apps ship no REUSE.toml or LICENSES/ directory. This
# repo ships both since WOO-579 (2026-09-17): a repo-wide `path = "**"` /
# `precedence = "closest"` floor in REUSE.toml makes every new file
# compliant on arrival whatever its type, and every piece of third-party
# material the repo bundles is annotated to what its publisher says, in
# `override` blocks that name the source. No enumeration of them here on
# purpose: the list written here first went stale inside the very pull
# request that wrote it, when review found five more clusters. REUSE.toml
# is the list, one commented block each. Measured before flipping:
# `reuse lint` compliant, 0 missing licences, 0 unused.
#
# Before this the REUSE row in the Quality Report was ❌ on every PR while
# the job itself reported success (`continue-on-error`), so nobody was
# blocked and nobody looked. Remko Huisman asked on portaliq (WOO-575) for
# the fleet to stop shipping that shape; this is the same change here.
#
# REUSE-IgnoreStart
# TWO regression modes remain. Measured on this branch, against the exact
# image the action runs (fsfe/reuse-action@v5 is FROM fsfe/reuse:5), and
# against fsfe/reuse:6 to see what the next bump brings.
#
# 1. Vendoring a file whose own SPDX header names a licence with no text
# under LICENSES/. Red build on reuse 5 and 6 alike. The fix is
# `reuse download <id>`, never removing the header.
#
# 2. A tracked TEXT file that MENTIONS an SPDX licence tag in prose —
# reuse parses the rest of the line as the licence expression. This PR
# tripped over it on an archived tasks.md that quoted a tag while
# describing the work. What it costs depends on the reuse major:
# reuse 5 (what CI runs today): a stderr ERROR, the file is skipped,
# the blanket then supplies its licensing info, lint still exits 0.
# Latent, not blocking. Verified by reproducing it on this branch.
# reuse 6 (fsfe/reuse-action@v6 exists; the day the shared workflow
# bumps): first-class non-compliance, "Invalid SPDX License
# Expressions: N", red build. Verified the same way.
# Both majors NAME the offending file in the error, so this is
# diagnosable; run `docker run --rm -v "$PWD":/data fsfe/reuse:6 lint`
# locally to see it before CI does.
# Fix: reuse's own ignore markers around the quoted tag — which is
# why this comment block sits between a pair of them. Their two names
# are deliberately not written out again anywhere inside the block:
# reuse matches the literal strings non-greedily, so a prose mention
# of the closing one ENDS the region at that line and leaves the rest
# of the block unprotected. That is a real trap — the first draft of
# this comment had exactly that shape.
# For openspec/changes/archive/**, which the repo treats as immutable
# history, REUSE.toml carries a `precedence = "override"` block
# instead, so nothing there is read for tags at all.
#
# This branch is compliant under BOTH majors, so the v6 bump will not
# land as a surprise red build here.
# REUSE-IgnoreEnd
reuse-blocking: true
# Run the Hydra mechanical quality gates against this PR's diff.
#
# This tier has never executed in this repository. `enable-hydra-gates`
Expand Down Expand Up @@ -407,10 +462,9 @@ jobs:
# call in src/, while `test:l10n:parity` asks whether every locale matches
# en.js key-for-key. One passing tells you nothing about the other.
#
# `check:l10n-js` is a THIRD question again: whether the generated browser
# catalogues (l10n/*.js) are in step with their .json sources. Both sides
# of this merge added one of these; neither replaces the other.
frontend-checks: '["check:specs", "test:l10n", "test:l10n:parity", "format", "check:schema-l10n", "check:l10n-js"]'
# There is no .js/.json parity leg: l10n/*.js is the browser catalogue and
# l10n/*.json the PHP one, separate sets with separate consumers.
frontend-checks: '["check:specs", "test:l10n", "test:l10n:parity", "format", "check:schema-l10n"]'
# ── Cost controls (see ConductionNL/.github#596, #599) ───────────────
#
# The fleet's CI was not slow, it was QUEUED. A Code Quality run does
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ scripts/l10n/harvest-*.json
.phpunit.result.cache
test-results/
playwright-report/

# Python bytecode caches (a .pyc was once committed by accident, WOO-579)
__pycache__/
*.pyc
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
- **`@self.files` on rendered objects is now opt-in for full file metadata.** By default, `@self.files` is a lightweight list of integer file IDs (`[123, 456, 789]`). Consumers that need full file metadata (`id`, `path`, `title`, `accessUrl`, `downloadUrl`, `type`, `extension`, `size`, `hash`, `published`, `modified`, `labels`) MUST add `_extend[]=@self.files` (or the equivalent shorthand `_extend[]=_files`) to their request. The change applies to **every** consumer of OpenRegister's render output, including `show` endpoints in dependent apps (e.g. opencatalogi `/publications/{catalogSlug}/{id}`). Migration is a one-line query parameter addition. The previous behavior — full metadata always served on show, no metadata on list — caused asymmetric responses across endpoints and paid the file-lookup cost on every show response regardless of need. The new contract is symmetric across show and list endpoints (both emit `@self.files` as IDs by default; both accept `_extend[]=@self.files` for full metadata) and is documented under the `files-render-extension` capability. **Note:** Using `_extend[]=@self.files` (or `_files`) on **list** endpoints is heavily discouraged because it triggers per-row file/tag lookups (N+1 queries scaling with page size) and will result in degraded performance. Use it only when full file metadata is genuinely required for every row. **SOLR limitation:** on SOLR/index-backed list endpoints, `_extend[]=@self.files` is not yet supported; the lightweight ID list is always returned and the response carries `@self.extend_unsupported: ["@self.files"]` so consumers can detect the mismatch programmatically. Use the database-backed path when full file metadata is required on lists.

### Fixed
- **Starting an OAuth2 connection works again, and each refusal answers with its own status.** `POST /api/credentials/oauth2/start` answered 500 on PostgreSQL and strict MySQL, because the pending state's vault key (71 characters) did not fit `oc_storages_credentials.identifier` (64); the nonce is now 32 characters, so the key is 60. A refusal now answers 400, 403, 409 (no OAuth2 client configured on this server) or 502 (a per-instance provider's server would not register a client), and only a genuine fault answers 500. A start that fails after minting a Mastodon client credential, or after storing its pending state, removes both again. **Upgrade note:** every Mastodon start made before this fix registered an application at the account's server and minted a local `generic-oauth2` credential ("OAuth2 client for https://…") before it failed, so affected users may find stray client credentials in their list, one per attempt. On PostgreSQL and strict MySQL none of those starts completed, so they are safe to delete. On a database that does not enforce the column length (SQLite), a start could complete, so delete such a client credential only when no Mastodon connection uses it as its `clientCredentialRef`. The matching applications at the Mastodon server were never authorised by the user, so they hold no access to the account.
- **Rotating a secret with `PUT /api/credentials/{id}` no longer leaves a half-applied update.** A rotated secret is now written before the metadata, so a failed rotation changes nothing. A `name` longer than 255 characters or an `allowedApps` entry longer than 64 now answers 400 `Invalid credential request` before anything is written, where it used to answer 500 after the save refused it. When the metadata cannot be saved after a rotation, the 500 now says `The secret was rotated, but the other changes could not be saved` rather than `Unable to update credential`, so a client must not read every 500 from this endpoint as "nothing changed".
- **Verified JSON object-typed property key order survives the PUT/create write path (#1720).** Traced the full write path (`ObjectsController::update` → `ObjectService::saveObject` → `SaveObject::prepareObjectForUpdate`/`prepareObjectForCreation` → `MagicMapper::prepareObjectDataForTable`/`rowToObjectEntity`): no PHP-layer reordering step exists (`setDefaultValues()` merges submitted keys first, defaults appended after; nothing applies `ksort` or rebuilds an object-typed value from schema-declared property order). The storage-layer cause of #1720 (PostgreSQL JSONB hashing object-typed columns) was already closed by the `json_ordered` column-type fix. Added `SaveObjectKeyOrderPreserveTest` (4 tests) locking in the drag-reorder round-trip and the PUT-semantic sibling-field guard through the real write path, alongside the pre-existing `MagicMapperKeyOrderColumnTypeTest`. (`put-preserve-key-order`)
- **Strict PDF anonymisation no longer fails on case-variant text and now redacts line-wrapped entities.** Three related fixes diagnosed on a Dutch government letter fixture: (1) `DocumentProcessingHandler::anonymizeDocument` orders the substitution map longest-needle-first so overlapping entities cannot clobber each other (a bare `Amsterdam` LOCATION no longer rewrites `De gemeente Amsterdam` before the longer `gemeente Amsterdam` needle matches, which left the longer entity unmatched and mis-typed). (2) `PdfTextReplacer::validateOutput` is now case-SENSITIVE (`mb_strpos`, mirroring the replacement engine's exact-case guarantee — previously a lowercase URL fragment like `www.amsterdam.nl`, never a detected entity, tripped the case-insensitive probe and failed fully-anonymised documents closed with `REASON_VALIDATION_FAILED`) and whitespace-normalised (both the re-extracted text and each needle are collapsed to single spaces, so entity text the PDF splits across a line break — `14 mei` / `2026` — is detected as residual instead of silently leaking). (3) The `ddn/sapp` pin is bumped to the cross-line-matching commit (Phase 4, Conduction/sapp PR #1) so wrapped entities are actually replaced: vertically adjacent same-font blocks are paired and matched across the wrap, giving the wrapped date its own placeholder. The dev-branch pin is temporary — re-pinning to a tagged sapp release is tracked in #69. On invalid UTF-8 from the re-extraction (the encoding-edge SAPP runs tracked by `font_encoding_misses`/`cid_split_mismatch`), strict mode now fails CLOSED (`validate.normalise`) instead of silently passing unaudited output; lenient mode falls back to un-normalised probing. Verified end-to-end through the DocuDesk anonymise flow: all 34 entities replaced, `unmatchedEntities: []`, strict validation passes. (#65)
- **Magic-table read path now coerces every property to its schema-declared PHP type.** Previously only `string` properties were coerced (and even then over-eagerly JSON-decoded scalar JSON like `"true"` / `"123"`); `boolean`, `integer`, `number`, `array`, and `object` properties were returned with whatever type the database driver produced — most visibly, booleans came back as `int 0`/`1` on MariaDB. A new shared `Service\Object\SchemaTypeConverter` is now the single source of truth for both `MagicStatisticsHandler::convertRowToObjectEntity` (single-object / list / POST / PUT response paths) and `MagicSearchHandler::convertRowToObjectEntity` (search path). Every endpoint that returns an `ObjectEntity` (`GET /api/objects/<uuid>`, `GET /api/objects`, `GET /api/search`, `POST /api/objects`, `PUT /api/objects/<uuid>`) now produces consistently schema-typed JSON. **Consumer-impact note:** consumers that depended on the broken behaviour (e.g. JS `value === 1` for "true") must switch to native truthy checks; OpenConnector register-backed sync flows and frontend widgets now receive correctly-typed values automatically. (`fix-magic-table-type-coercion`)
Expand Down
38 changes: 38 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ Every pull request triggers our automated quality pipeline. **All checks must pa
| ----------------------------- | ---------------------------------------------------------- |
| **License (npm + composer)** | Ensures all dependencies use approved open-source licenses |
| **Security (npm + composer)** | Checks for known vulnerabilities in dependencies |
| **REUSE compliance** | Every file has copyright + licence info, and every licence it names has a text under `LICENSES/`. **Blocking** — a red REUSE check fails the build |

### Running Quality Checks Locally

Expand All @@ -144,8 +145,45 @@ composer phpmd # PHPMD mess detection
# Frontend
npm run lint # ESLint
npx stylelint "src/**/*.{css,scss,vue}" # Stylelint

# Licensing (same tool CI runs)
docker run --rm -v "$PWD":/data fsfe/reuse:5 lint
```

### Licensing (REUSE)

`REUSE.toml` in the repository root declares copyright and licence for every
file. Most files are covered by a blanket entry; third-party material gets its
own block naming the publisher. New files normally need nothing — PHP files keep
carrying their own SPDX header, and everything else falls under the blanket.

If the REUSE check goes red, it is almost always one of three things:

1. **A file names a licence that has no text under `LICENSES/`.** Add it:

```bash
docker run --rm -v "$PWD":/data fsfe/reuse:5 download MIT
```

2. **You added third-party material.** Add an `[[annotations]]` block to
`REUSE.toml` naming the real rights holder *before* relying on the blanket —
the blanket will otherwise silently declare it Conduction's. Blocks are
ordered: the last matching one wins, so third-party blocks come after the
blanket and use `precedence = "override"`.

3. **You wrote an SPDX tag in prose** — explaining the convention in a comment,
a README or a workflow file — and REUSE parsed your explanation as a real
tag. Wrap the passage in REUSE's ignore markers; `.github/workflows/`
`code-quality.yml` has a worked example of both markers and the rule for
using them. Two traps, both of which this repository has already hit: naming
the closing marker inside the region terminates it early, and a licence
identifier mentioned in prose without a licence text under `LICENSES/` fails
the same way a real one does.

Run the lint locally before pushing — it is the same image and version CI uses,
and it takes under a minute. `fsfe/reuse:6` is stricter about invalid SPDX
expressions and is worth a second run if the failure is confusing.

## App Store Release Process

Releases to the Nextcloud App Store are fully automated via GitHub Actions. They are triggered by merging PRs into `beta` or `main`. Version numbers are calculated automatically from PR labels.
Expand Down
Loading
Loading