feat(content-drive): browse scopes for All, site root and System Host (#37426) - #37487
feat(content-drive): browse scopes for All, site root and System Host (#37426)#37487zJaaal wants to merge 10 commits into
Conversation
… and System Host Content Drive has one browse scope today: the whole current site at any depth, with System Host mixed in. Selecting the site and browsing the site root are the same request, and System Host cannot be reached on its own. Specifies three scopes picked from the sidebar. All (the whole site, content only, read-only) sits above the site hierarchy, whose site row now means the site root. System Host sits below it, listing shared content on its own and accepting content dropped onto it. The "Show Shared Assets" chip becomes "Show System Host" and applies only to All. Callers that ask for no scope keep today's behavior, which is what leaves the Asset Picker and the other consumers of the shared listing untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Claude finished @zJaaal's task in 1m 23s —— View job Review — Content Drive browse scopes (spec-only PR)
This PR adds spec/design docs only — no production code — so there are no runtime bugs to find. I focused on whether the checkable claims in the docs are actually true against the codebase, since a spec that cites the wrong seam sends the implementation phase the wrong way. New Issues
Verified accurate (worth recording)These claims all check out against the code, so the design rests on solid ground:
Note (non-blocking)The two prior reviewer gaps (query-path parity per heuristic; per-consumer back-compat enumeration) are addressed by FR-012, FR-028, SC-004 and SC-007. Those are now spec requirements; whether the enumeration is complete is a plan/tasks-phase concern, not something checkable here. Net: one doc reference to correct before the spec is trusted as the implementation contract. Not a blocker for the spec's design, which is sound. |
All is the default only on a cold open. A URL that names a scope opens on that scope; one that names none opens the folder it points at, or All when it points nowhere. That keeps links made before this feature meaning what they meant, and it makes the scope behave like every other filter rather than like a preference the URL cannot override. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The spec looks solid overall — two acceptance-criteria gaps I'd flag before signing off: 1. Query builder parity has no dedicated testThe driving issue notes Given this is a real, already-identified bug, I'd want an explicit acceptance scenario that exercises both query heuristics ( 2. No-scope backward compatibility isn't broken down by consumerSC-007 says "surfaces other than Content Drive keep listing exactly what they list today," but there are 6 named consumers of the shared listing:
One aggregate success criterion doesn't tell us which of those get an actual regression test vs. which are assumed safe by inspection. Could the plan/tasks phase enumerate this explicitly? |
One URL value says where the drive is browsing, rather than a scope beside a path that could disagree with it: absent means All, `/` means the site root, a deeper path means that folder, and a reserved word means System Host. Real folder paths all begin with `/`, so a reserved word can never collide with one, and links made before this feature keep meaning what they meant. The search rule was worded backwards. It said a selection returns the same items with or without a search, which reads as "search does nothing" and contradicts the success criterion that already allows for what a search excludes. It now says filtering may only remove items from the scope, never add items from outside it, whichever internal search path serves the request, and both paths are exercised for the site root and System Host rather than only the one that runs by default. Saying All and System Host have none of the behaviors of folders was too broad, since System Host does take content. Narrowed to structure. Backward compatibility is no longer one blanket claim over eight consumers: the shared seam they all reach gets a test, and each consumer is recorded as covered by it or checked by inspection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Both added in Query-path parity. You are right that it was only implied. Two things changed. The requirement it hung off was actually worded backwards: it said a selection returns the same items with or without a search, which reads as "search does nothing" and contradicts the success criterion that already allows for what a search legitimately excludes. It now says a search or field filter may only remove items from the selected scope and never add items from outside it, whichever internal search path serves the request. On top of that there are now explicit acceptance scenarios for the site-root and System Host scopes stating both paths return the same items, and the Legacy section spells out that only one of the two runs by default, so proving they agree means deliberately exercising each rather than waiting for the non-default one to turn up. Concretely that is flipping Per-consumer backward compatibility. Added as a requirement rather than left to the plan, since it is the promise and not just how we check it: the claim must be demonstrated rather than assumed, and every consumer must be recorded as covered by a test or checked by inspection, with none unaccounted for. The success criterion now says the same. Worth knowing how small that turns out to be in practice. All eight of those callers reach the listing through one builder, and none of them sets the System Host flag or the folder-skip flag today. So the entire risk collapses to a single question: does the new three-state default to the same host clause the boolean produces today? One test pinning the default at that shared seam covers every consumer at once, and the rest of the list is inspection. The plan will carry the enumeration so it is visible rather than assumed. Reply written by Claude on @zJaaal's behalf. |
|
All three addressed in The search requirement was worded backwards. Correct, and it was the one worth catching. It now says a search or field filter may only remove items from the selected scope and never add items from outside it, which is the invariant that was meant, and it adds that the answer must not depend on which internal search path served the request. "None of the behaviors that belong to folders" was too absolute. Also correct. Narrowed to structure: no expansion control, no children, nothing beneath them to navigate into, with an explicit note that this does not stop System Host accepting content. The site-row scope had no URL representation. This was the real gap, and the fix went further than the suggestion. Rather than adding a scope parameter beside the existing location, the spec now requires a single value to say where the drive is browsing, because two values can disagree and then neither is the answer. Absent means All, Reply written by Claude on @zJaaal's behalf. |
Content Drive is separately gaining a search scope (#37479), which says which fields a search reads. This one says where you are browsing. Two different things, and "scope" on its own would name either, so every mention here is now spelled in full and the Key Entities entry says what the other one is. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s' into 37426-content-drive-browse-scopes
|
|
Two callers share POST /v1/drive/search, and one of them is owned elsewhere, so what the new field means when it is absent is the whole promise. Written down rather than left to the implementation: omitting the browse scope returns what it returns today, byte for byte, and the field is deliberately NOT defaulted to ALL, because ALL as unconditional folder-skipping would silently turn the Asset Picker's folder requests recursive. An explicit scope is valid only at the site root. A folder path with any scope is refused rather than resolved by precedence, following the bulk upload form: picking one of two contradictory statements puts content somewhere the caller did not choose. plan.md, research.md and quickstart.md stay local per .gitignore:228. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…s' into 37426-content-drive-browse-scopes
Proposed Changes
Content Drive can express one browse scope today: the whole current site, at every depth, with System Host mixed in. Browsing "the site" and browsing "the site root" are the same request, and System Host cannot be reached on its own. This PR splits that into three browse scopes picked from the sidebar. Spelled in full throughout: Content Drive is separately gaining a search scope (#37479) that says which fields a search reads, and bare "scope" would name either.
/means the site root, a deeper path means that folder, and a reserved word means System Host. Links made before this change keep meaning what they meant.The spec lands first, in
specs/37426-content-drive-browse-scopes/spec.md; the implementation follows in this same PR. Draft until both are in.The contract delta is worth reading on its own if you own a caller of
POST /v1/drive/search:contracts/drive-search-browse-scope.md. Short version: omitting the new field returns what it returns today, byte for byte, and the field is deliberately not defaulted, because defaulting it would silently turn the Asset Picker's folder requests recursive.Checklist
Additional Info
Reviewers: the spec is the thing to read now. The code will be written against it, so a disagreement is much cheaper to settle here than after the implementation.
Fixes #37426
🤖 Generated with Claude Code