Skip to content

docs(openspec): OpenSpec pass batch 3 of 3, ten keepiq audit, clients, crypto and sharing changes - #781

Merged
rubenvdlinde merged 4 commits into
developmentfrom
parity/openspec-pass-3
Sep 27, 2026
Merged

rubenvdlinde merged 4 commits into
developmentfrom
parity/openspec-pass-3

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

The OpenSpec pass for keepiq, batch 3 of 3: the audit, clients, crypto and sharing changes. With this PR every keepiq build row has a change. It writes specs only; nothing is implemented.

Changes in this PR

  • audit-siem-vendor-connectors: audit-14
  • clients-extension-store-release: clients-01, clients-04
  • clients-extension-unlock-lock-and-accounts: clients-06, clients-21, crypto-09
  • clients-ssh-agent: clients-13
  • clients-offline-edits: clients-19
  • crypto-organisation-account-recovery: crypto-11
  • crypto-new-device-approval: crypto-24
  • sharing-federated-recipients: sharing-17
  • sharing-team-folder-manager-role: sharing-18
  • sharing-use-only-and-expiring-shares: sharing-24, sharing-25

Design calls worth a reviewer's eye:

  • crypto-organisation-account-recovery keeps the server keyless (ADR-005): the recovery key is generated in a recovery officer's browser and wrapped to each officer's certificate; the approval threshold is server-enforced with a vault-key proof per approval. The design states that the approving officer briefly holds the recovered key and that a colluding server operator plus one officer could bypass the threshold.
  • crypto-new-device-approval seals the unlock key with HPKE to the new device, one-time pickup, 15 minute expiry; the administrator path exists only through the recovery change above.
  • clients-offline-edits removes the requirement "Offline mode is strictly read-only" from offline-readonly-cache and answers that spec's reason: the recipient fan-out is computed only at replay time against current certificates, and conflicts use a baseUpdatedAt precondition (409). Off by default.
  • clients-ssh-agent is a subcommand of the existing Go CLI, not a desktop app (the product records no native app); it adds the CLI's first dependencies (golang.org/x/crypto, golang.org/x/sys) and govulncheck. Linux and macOS only.
  • sharing-team-folder-manager-role adds a manage grade above write with RENAMED and MODIFIED deltas on folder-permission-grades, keeping every existing scenario. TeamFolderMember::effectiveGrade() (lib/Db/TeamFolderMember.php:144) would today turn a stored manage into read; the change's tasks cover it.
  • sharing-use-only-and-expiring-shares states that use-only is client-enforced in a zero-knowledge vault, and lists the refusals the server can still make (onward sharing, recipient edits, version reveal). Share expiry is a new access_expires_at, because expires_at already means credential expiry.
  • sharing-federated-recipients uses OCM with admin-pinned partner instances and needs Nextcloud 33 for signed OCM requests; it stays off on 32.

Matrix and decision edits in this PR

  • specified on audit-14, clients-01, clients-04, clients-06, clients-13, clients-19, clients-21, crypto-09, crypto-11, crypto-24, sharing-17, sharing-18, sharing-24 and sharing-25.
  • clients-01 corrected: its note said the extension matches only the user's own secrets, but every shared or team-folder copy is a row owned by the recipient (lib/Service/RecipientSecretCopyService.php:112-113, lib/Service/TeamFolderShareService.php:295), so the owner-scoped match (lib/Controller/ExtensionController.php:195) already returns them. The note and the decision reason in gap-decisions.json now say so; the change specifies only the store release.

Found while writing, not in these rows

  • extension-totp-autofill says the extension may fill the code on the page after sign-in, but the code fills once, at fill time (browser-extension/src/background/service-worker.js:141).
  • browser-extension/manifest.json requests the scripting permission, which nothing calls, and its description contains an em-dash.
  • sharing-17's matrix evidence cites EncryptionSuiteProvisioningService.php:331, the docblock; the function body is at :339.

Checks, by exit code

  • openspec validate --changes: 39 passed, 1 failed; the failure (migrate-emergency-access-on-rotation) is on development and untouched. Each of the ten changes passes openspec validate <name> --type change --strict; helper-2 also test-archived all ten on a throwaway copy, and the RENAMED, MODIFIED and REMOVED deltas applied cleanly.
  • parity_verify.py --strict: no strict finding; only the census of 150 unknown cells, unchanged. Schema validation ran and passed.
  • npm run lint: exit 0.
  • composer check:strict (private HOME and TMPDIR, COMPOSER_PROCESS_TIMEOUT=0): exit 1, the same 2 inherited PHPUnit errors as docs(openspec): OpenSpec pass batch 1 of 3, keepiq gap decisions and 11 changes #767 and docs(openspec): OpenSpec pass batch 2 of 3, ten keepiq admin and apps changes #769 in tests/Unit/Migration/ConsolidatedSchemaMigrationTest.php (1,346 tests); lint, phpcs, phpmd, psalm and phpstan pass. The branch changes nothing outside openspec/.
  • No em-dash, en-dash or double dash in any new file; every tasks.md has at most 16 checkboxes.

🤖 Generated with Claude Code

… unlock and accounts, SSH agent, offline edits
…roval, federated recipients, team-folder managers, use-only and expiring shares
audit-14, clients-01, clients-04, clients-06, clients-13, clients-19,
clients-21, crypto-09, crypto-11, crypto-24, sharing-17, sharing-18,
sharing-24 and sharing-25 are specified by the ten changes of this
batch.

clients-01: matching already covers shared and team folder secrets,
because every recipient copy is a row owned by the recipient
(RecipientSecretCopyService.php:112-113) and the extension match is
owner-scoped (ExtensionController.php:195). The note and the decision
reason now say so; the missing half is the store release.
@rubenvdlinde
rubenvdlinde merged commit b5727e0 into development Sep 27, 2026
36 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/keepiq @ 86e9a42

Check PHP Vue Security License Tests
lint ✅
phpcs ✅
phpmd ✅
psalm ✅
phpstan ✅
phpmetrics ✅
eslint ✅
stylelint ✅
build ✅
check-manifest ✅
test-l10n ✅
format ✅
check-l10n-js ✅
check-schema-l10n ✅
composer ✅ ✅ 114/114
npm ✅ ✅ 660/660
app:check-code ⏭️
info.xml ✅
REUSE ✅
lockfile sync ✅
PHPUnit ⏭️ not run for this diff — no file in this diff matches the code globs, and none carries a source extension — the heavy tier has nothing to decide about it.
Newman ✅
Playwright ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it on any branch from the Actions tab, or locally with npx playwright test.
Hydra gates ✅

Quality workflow — 2026-09-27 18:48 UTC

Download the full PDF report from the workflow artifacts.

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