Files
kite/.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-04-PLAN.md
T
curo1305andClaude Sonnet 4.6 73328eee0b docs(12.1): add phase 12.1 planning artifacts — Nextcloud root listing fix
Plans 01–04, CONTEXT, PATTERNS, RESEARCH, UAT, and .gitkeep for
the fix-nextcloud-root-listing-and-sync-visibility sub-phase.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 20:34:47 +02:00

19 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
12.1 04 execute 4
12.1-01
12.1-02
12.1-03
backend/tests/test_nextcloud_live.py
backend/tests/fixtures/cloud/nextcloud_expected_root.json
backend/pytest.ini
frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js
.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md
backend/main.py
frontend/package.json
frontend/package-lock.json
AGENTS.md
README.md
RUNBOOK.md
SECURITY.md
false
CONN-04
CLOUD-01
CACHE-01
SYNC-01
truths artifacts key_links
An opt-in read-only live test browses the configured Nextcloud root through the owner-scoped connection-ID DocuVault API as testuser@docuvault.example
Live execution never prints secrets, the full URL, or unexpected provider names and never downloads/mutates provider data
Live validation has a nonblocking sanitized diagnostic mode and a separate exact acceptance mode enabled only by an owner-confirmed tracked manifest
Mocked and live evidence together prove folders/files, kind, provider identity, freshness, zero-byte, and owner isolation
Full tests, security/dependency/secret gates, docs, version, atomic commit, and push complete before Phase 12.1 closes
path provides contains
backend/tests/test_nextcloud_live.py Opt-in sanitized live Nextcloud adapter and connection-ID API smoke test_nextcloud_root_diagnostic
path provides contains
backend/tests/fixtures/cloud/nextcloud_expected_root.json Owner-confirmed, non-secret exact root name/kind acceptance manifest owner_confirmed
path provides contains
.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md Nyquist matrix and live/mock/security evidence 7 of 10
path provides contains
SECURITY.md Phase 12.1 threat and gate evidence without secrets/provider content Phase 12.1
from to via pattern
NEXTCLOUD_URL/NEXTCLOUD_USER/NEXTCLOUD_APP_PASSWORD backend/tests/test_nextcloud_live.py ignored environment read in process memory only os.environ|getenv
from to via pattern
testuser@docuvault.example GET /api/cloud/connections/{connection_id}/items isolated test DB user, encrypted connection, authenticated API request testuser@docuvault.example
from to via pattern
supplied expected manifest exact live signoff explicit discrepancy reconciliation gate Documents|Reasons to use Nextcloud.pdf
Prove the repaired flow against the designated test account without risking credentials or provider data, reconcile the known manifest discrepancy before exact-name acceptance, then close Phase 12.1 with full validation, security, documentation, versioning, commit, and push protocol.

The live test is intentionally opt-in and read-only. Missing credentials skip with a prerequisite message; a manifest discrepancy blocks exact-name signoff rather than mutating the provider or silently changing expectations.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-CONTEXT.md @.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-RESEARCH.md @.planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-PATTERNS.md @.planning/phases/12-cloud-resource-foundation/12-VALIDATION.md @.planning/phases/12-cloud-resource-foundation/12-SECURITY.md @.planning/phases/12-cloud-resource-foundation/12-VERIFICATION.md @AGENTS.md Task 1: Build and run the nonblocking sanitized live diagnostic backend/tests/test_nextcloud_live.py, backend/pytest.ini, .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md - .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-CONTEXT.md — credentials, user, expected manifest, and read-only rules - .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-RESEARCH.md — sanitized 207/10/7-of-10 probe evidence - backend/tests/conftest.py — isolated DB/auth fixture conventions - backend/tests/test_cloud.py — connection creation and connection-ID browse patterns - backend/tests/test_cloud_security.py — owner/admin/credential/no-byte assertions - backend/storage/cloud_utils.py — credential encryption and URL validation Add a `live_nextcloud` pytest marker excluded from ordinary test runs unless explicitly selected. Read only `NEXTCLOUD_URL`, `NEXTCLOUD_USER`, and `NEXTCLOUD_APP_PASSWORD` from the ignored environment at runtime; if any are absent, skip with a generic prerequisite message naming variable keys only. Never load or print `.env`, and never place values in parametrization IDs, assertion diffs, exceptions, snapshots, logs, artifacts, or command lines.
Create `test_nextcloud_adapter_read_only_root_metadata`, `test_nextcloud_root_diagnostic`, and an authenticated `test_nextcloud_connection_id_browse_as_designated_user`. In an isolated test database, provision/resolve the regular DocuVault user exactly `testuser@docuvault.example`, encrypt the live connection credentials through production helpers, then browse root through `GET /api/cloud/connections/{connection_id}/items`; also assert foreign-user/admin denial. The test may issue metadata-only DAV requests required for listing. Install a request guard that rejects byte GET/media and PUT/POST/PATCH/MKCOL/MOVE/COPY/DELETE methods before network dispatch; assert quota and MinIO/object storage are unchanged.

In diagnostic mode compare in memory against the ten owner-supplied candidate names, but do not assert exact equality and do not claim acceptance. Emit only total count, expected-match count, missing supplied names, unexpected count, completion state, and kind counts; never emit unexpected names. The diagnostic must exit successfully when transport/security/read-only invariants pass even if the candidate manifest is 7/10, while recording `manifest_status: unconfirmed`. Catch/redact transport errors into stable codes so neither full URL nor credentials enter pytest output. Assert captured logs/output contain none of the secret values or full URL.

Record the contract, commands, skip behavior, sanitized result fields, and threat references in 12.1-VALIDATION.md. Do not record unexpected live names.
- ordinary pytest does not contact Nextcloud and missing variables produce an explicit safe skip - selected live tests authenticate only as the designated regular app user and use connection-ID browse - network guard permits metadata listing but rejects download and every mutation method - output contains no credential, full URL, raw response body, or unexpected provider name - manifest mismatch is diagnostic-only and nonblocking before owner confirmation cd backend && pytest -q tests/test_nextcloud_live.py -m live_nextcloud The opt-in diagnostic safely proves connectivity/listing invariants and reports sanitized drift without claiming exact acceptance. Task 2: Reconcile the known 7-of-10 fixture discrepancy before exact signoff backend/tests/fixtures/cloud/nextcloud_expected_root.json, backend/tests/test_nextcloud_live.py, .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md - .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-RESEARCH.md — three supplied names not exactly matched in sanitized probe - backend/tests/test_nextcloud_live.py — supplied expected manifest and safe mismatch report Run the live smoke and inspect only its sanitized count/missing-expected output. The prior probe found 10 children but only 7 exact supplied-name matches; therefore do not declare the ten-name assertion accepted merely because item count is 10. If the same mismatch remains, stop and ask the project owner to compare the three supplied expected names (`Manual Nextcloud.png`, `Nextcloud Intro.mp4`, `Template credits.md`) with the Nextcloud UI and state which source is authoritative. Do not reveal the three unexpected provider names and do not rename/delete/upload anything.
After explicit owner confirmation, store the authoritative names and kinds in tracked `backend/tests/fixtures/cloud/nextcloud_expected_root.json` with no URL, username, credential, provider ID, timestamp, or unexpected-name discovery data; include `owner_confirmed: true` and a short non-secret provenance note. Only then add/enable `test_nextcloud_expected_root_manifest`, loading that fixture. If the original supplied expectation is authoritative, leave its names unchanged and treat the provider account as requiring external fixture correction. Re-run until exact set equality and exact kind equality pass. Record the owner-confirmed disposition and only sanitized counts in 12.1-VALIDATION.md.
- exact-name signoff is blocked while only 7/10 supplied names match - no unexpected provider names are printed or persisted during reconciliation - any expected-manifest change has explicit owner confirmation, not inference from live output - final live result is exact set and kind equality, not count-only acceptance - provider content remains unchanged cd backend && pytest -q tests/test_nextcloud_live.py -m live_nextcloud -k expected_root_manifest The owner has reconciled the fixture discrepancy and the live account passes exact root-name and kind acceptance without provider mutation. Task 3: Run full regression, security, environment, and rendered-flow gates frontend/src/views/__tests__/CloudFolderRenderedFlow.test.js, .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md, SECURITY.md, RUNBOOK.md - AGENTS.md — mandatory tests, security checks, environment contract, and deployment exclusions - .planning/phases/12-cloud-resource-foundation/12-VALIDATION.md — baseline Nyquist matrix and commands - .planning/phases/12-cloud-resource-foundation/12-SECURITY.md — inherited threat evidence - SECURITY.md — project security evidence format - RUNBOOK.md — operational cloud/migration guidance Add an executable Vue Test Utils rendered-flow test `CloudFolderRenderedFlow.test.js` that mounts the real CloudFolderView with StorageBrowser/BreadcrumbBar (stubbing only network/router boundaries), renders mixed root folders/files, clicks a folder whose opaque reference contains reserved characters, navigates back via lineage breadcrumbs, and renders refreshing/warning/fresh server states while cached rows remain visible. Run it in the normal Vitest command. Use the live account only for the separate sanitized API smoke; do not place provider names or credentials in rendered snapshots.
Run `bandit -r backend/`, `pip audit`, `npm audit --audit-level=high`, security-invariant tests, and `gitleaks detect --source . --no-banner --redact` as the concrete repository/history secret scanner (install the pinned approved binary before execution if absent; absence blocks the gate). Also run `git ls-files '.env' '.env.*'` and require only approved example files. Verify no new high/critical findings, no tracked `.env`, no secret values in current history/diff, no raw provider URL/error leakage, no admin/foreign-user access, and no provider byte/mutation/quota activity. Resolve introduced findings without skips, suppressions, or broad exception swallowing. Update validation/security/runbook evidence with commands and sanitized outcomes only.
- four-provider focused contract, live exact acceptance, full suites, and build pass - Compose config resolves every required variable non-empty without printing values - Bandit and pip/npm audits have zero introduced high/critical findings - secret scan and git diff contain no credentials/full live URL - rendered root/nested/freshness behavior matches API truth and uses StorageBrowser docker compose config --quiet && gitleaks detect --source . --no-banner --redact && test -z "$(git ls-files '.env' '.env.*' | grep -v '^\.env\.example$')" && cd backend && pytest -q tests/test_cloud_provider_contract.py tests/test_cloud_backends.py tests/test_webdav_backend.py tests/test_cloud_items.py tests/test_cloud.py tests/test_cloud_security.py && pytest -q tests/test_nextcloud_live.py -m live_nextcloud && pytest -v && bandit -r . && pip audit && cd ../frontend && npm test -- --run src/views/__tests__/CloudFolderRenderedFlow.test.js && npm test && npm run build && npm audit --audit-level=high Automated, live, rendered, security, dependency, secret, and environment gates pass with sanitized evidence. Task 4: Close documentation, version, commit, and push protocol backend/main.py, frontend/package.json, frontend/package-lock.json, AGENTS.md, README.md, RUNBOOK.md, SECURITY.md, .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-VALIDATION.md - backend/main.py — backend version source of truth - frontend/package.json — frontend version source of truth - frontend/package-lock.json — lockfile root/package version entries - AGENTS.md — current state, shared module map, documentation/version/Git protocols - README.md — cloud browse feature and environment documentation - .planning/ROADMAP.md — Phase 12.1 boundary and Phase 13/14 exclusions Update AGENTS.md current state to Phase 12.1 complete and add any new canonical listing/freshness helper to the backend shared-module map with a no-duplication rule. Update README with truthful provider-neutral browse behavior and opt-in live test variable names only; never add values. Update RUNBOOK with safe live-smoke invocation, redaction expectations, warning semantics, and fixture-reconciliation procedure. Update SECURITY.md and 12.1-VALIDATION.md with final evidence and inherited controls.
Increment the current backend/frontend patch version exactly once for Plan 04 in backend/main.py, frontend/package.json, and both relevant package-lock entries; earlier plans have already performed their own required per-plan bumps. Use source values at execution time and keep all versions identical. Do not claim Phase 13 mutations or Phase 14 byte cache behavior.

Run a dedicated security agent on Plan 04's diff and resolve or escalate every finding. Re-run focused/full tests, rendered test, gitleaks, build, security gates, and `docker compose config --quiet` after docs/version changes. Review `git diff --check`, `git status`, and staged diff for secrets/unrelated user changes. Stage only Plan 04 live-test/fixture/rendered-test/planning/docs/version files explicitly, commit atomically as `test(12.1): verify live cloud browse integration`, and push immediately. Never amend or accumulate Plans 01-03, stage `.env`, or overwrite unrelated work.
- AGENTS/README/RUNBOOK/SECURITY describe shipped behavior and explicit Phase 13/14 exclusions - documentation names environment keys only and contains no credential, full URL, or unexpected live provider name - backend/package/lock versions match after one patch bump - final test/build/security/config gates remain green - Plan 04 has its own atomic commit and push without unrelated files or `.env`; Plans 01-03 remain separate commits docker compose config --quiet && git diff --check && cd backend && pytest -v && cd ../frontend && npm test && npm run build && npm audit --audit-level=high Phase 12.1 is documented, versioned, fully verified, atomically committed, and pushed with no secret or scope leakage.

<threat_model>

Threat ID Threat Mitigation and evidence
T-12.1-16 Live credentials/full URL leak through pytest/logs Runtime env only, generic failures, capture assertions, no values in IDs/commands/artifacts
T-12.1-17 Live smoke mutates/downloads user data Network method guard; metadata-only requests; no-byte/no-quota assertions
T-12.1-18 Live connection crosses user/admin boundary Designated regular user plus foreign/admin negatives through connection-ID API
T-12.1-19 Count-only test accepts wrong root Exact set and kind equality; blocking 7/10 reconciliation checkpoint
T-12.1-20 Unexpected provider names become persisted sensitive metadata Unexpected count only; no names in output/docs/fixtures
T-12.1-SC Supply-chain or committed-secret regression Bandit, pip/npm audits, secret scan, staged diff review before commit/push
</threat_model>
1. Ordinary tests skip live access safely; selected live tests use only the three named environment keys. 2. Live adapter and connection-ID API smoke pass as the designated user with exact names/kinds after explicit discrepancy reconciliation. 3. Network guard and DB assertions prove no provider mutation, download, MinIO, or quota change. 4. Shared four-provider, backend/frontend full, build, security, audit, secret, and Compose gates pass. 5. Docs/version are synchronized; atomic commit and push succeed without `.env` or unrelated changes.

<success_criteria>

  • The connected Nextcloud root is visible through DocuVault and matches an owner-confirmed exact manifest.
  • The test design validates all providers through one contract while preserving provider-specific fixtures and pagination.
  • Freshness is truthful from adapter completion through API, store, and rendered browser.
  • Credentials/provider data remain private and provider content remains untouched.
  • Phase 12.1 closes without importing Phase 13 mutations or Phase 14 byte caching. </success_criteria>

Create .planning/phases/12.1-fix-nextcloud-root-listing-and-sync-visibility/12.1-04-SUMMARY.md when complete, then update roadmap/state through the normal GSD phase-close workflow.