Date: Mon, 7 Aug 2000 16:20:17 -0400 (EDT) Message-Id: <200008072020.QAA08062@tantalum.atria.com> From: "Geoffrey M. Clemm" <geoffrey.clemm@rational.com> To: ietf-dav-versioning@w3.org Subject: Re: Review of 06 From: jamsden@us.ibm.com I liked the semantic distinction between the target, specified in a target-selector header and the default-target, defined by a property of the versioned resource and selected by default if the target-selector wasn't specified. This distinction was not needed in the protocol document, so it seemed simpler not to make it. The problem with the current definition of SET-TARGET is that it doesn't focus on the point of SET-TARGET. Modifing the state of a version selector isn't what's interesting. The fact that a new default version is selected is. I disagree. Changing the target selected by a version selector is a interesting only because it changes the state of that versioned resource, as reflected by the results of GET and PROPFIND. section 2.2: I don't like the language "will cause the version selector to display the content".... version selectors don't display anything by any meaning of the verb display. The sentence should read "The SET-TARGET request will cause references to the version selector to operate on the content and properties of the specified version." Similarly, section 2.3 second paragraph: "For certain methods, a Target-Selector request header can be used to make references to a version selector operate on the content and properties..." I agree that we should get rid of the word "display". I'd prefer "The SET-TARGET request sets the content and dead properties of the version selector to be those of the specified version". Section 3.3.2 DAV:auto-version: should we say "to be effectively proceeded by a CHECKOUT and followed by a CHECKIN..." to allow servers more flexible implementations? Since the protocol cannot force a server to any particular implementation, but can only require that it satisfies the pre and post conditions defined by the protocol, I believe the word "effective" would be redundant here, and even possibly misleading since it might lead a reader to believe that the pre and postconditions are somehow weakened by the use of the word "effective". 3.4.2 reference to merging should be removed - its an advanced versioning concept. I think the forward reference here is justified, since otherwise it is unclear why this property should be a set. However, this brings up an interesting question. There is no DAV:single-checkout property on a version and/or version selector, so it is possible for many users, or the same user, to checkout the same version more than once creating multiple successors for the same version. Yes. But there is no merge method, and the DAV:predecessor-set is protected. So there is no way to merge these successors back into a single line of descent. Is it reasonable for the spec to allow "forking" without merging? The client can perform a merge, but cannot indicate that a merge has been performed unless the server supports the DAV:predecessor-set property for working resources, or supports the MERGE method. This seems reasonable to me. 3.2.1 creator-displayname has limited value: can be changed anytime by anyone, syntax isn't specified, doesn't correspond to a principal. Why not use the principal? <geoff> The purpose of "creator-displayname" is not to identify a principal (that's something the ACL protocol will introduce), but just to give some string that a client can use to print out something (hopefully) meaningful to the user. </geoff> The point I was making is that its the principal (in a DAV:creator protected property) that's of value, not the display name. The question is, do we want to specify this property too so we have a more reliable way of identifying who created a version, and if so, will we require an authentication header to specify it on checkin? Until we have agreed on the semantics of a creator principal, we don't have an interoperable way of storing it. The creator-displayname property was just an easy way to display what systems store today. When semantics for a principal have been agreed upon, then the creator-principal will often be more useful than creator-displayname, but I don't think that the versioning group should take on the task of defining interoperable semantics for principal. 3.5.1 DAV:checked-out needs to be DAV:predecessor-set for working resources to be consistent with support for advanced versioning merging. Why not use the same property for the same function in working resources and versions? <geoff> The DAV:checked-out property is needed to specify what version will be the target when an UNCHECKOUT is performed, while DAV:predecessor-set determines what the DAV:predecessor-set of the new version will be. Note that although the DAV:predecessor-set is initialized to be the DAV:checked-out version, the client can change this (but it can't change the DAV:checked-out property). </geoff> UNCHECKOUT works on the working resource, not the version, and just deletes it. I still think it would be more uniform, and therefore simpler for clients, if the DAV:predecessor-set was used for this. But I may not understand your point above. When you UNCHECKOUT a working resource in a workspace, the working resource is replaced by a version selector. You need the DAV:checked-out property of the working resource to determine what the DAV:target property of the version selector will be (the DAV:predecessor-set may contain multiple versions, and therefore cannot be used to answer this question unambiguously). The DAV:predecessor-set is protected. Did you mean to do that? That's why I mentioned there no way to merge above. The DAV:predecessor-set of a working resource is not protected (although the DAV:predecessor-set of a version is). 5. a version selector isn't checked out, the target version is. <geoff> Since you issue a CHECKOUT operation against a versioned resource, I think it makes sense to say that you "check out a version selector". When a Workspace header is used, you cannot issue a checkout against a version URL (only against a versioned resource URL), so for compatibility between workspace and non-workspace checkouts, it is best to restrict a checkout to be against a version selector. </geoff> As a matter of style, I prefer to indicate the method operation on what actually gets effected. In the case of CHECKOUT, the target URL is the version selector, but its the version that gets the new successor which seems to be more to the point. In a workspace, a CHECKOUT replaces the version selector with a working resource, so the CHECKOUT is very much an operation on the version selector. A CHECKOUT does not add a new successor to the version being checked out. Why can't you CHECKOUT using a version URL? Wouldn't the workspace header be ignored in this case, just like the target-selector header? If a system requires that checkouts be done in the context of a workspace, all attempts to CHECKOUT a version URL will fail, because no workspace context is specified (either explicitly with a workspace header or implicitly by identifying a version selector). Section 5, add a second paragraph: "For any request whose request URL identifies a version selector, and no Target-Selector is specified, the request MUST act as if the state of the version selector was a copy of the version specified in the DAV:target property of the versioned resource." I believe this only affects GET and PROPFIND, so I added this to those particular methods (i.e. 5.3 and 5.5). 5.1 Specify the status codes (I don't have the WebDAV spec in front of me, just pick the next available codes). Anybody know what the next available codes are? 5.6 Why not auto-version a specific version given a version URL. To the server, this is just the same as resolving a version selector and target-selector or DAV:target to a specific version and then auto versioning that version. Because the next time you did a GET on that URL, you would not see the results of the PUT, so auto-versioning a version-URL would not satisfy HTTP semantics. 5.7 What's the motivation for having DELETE on a version or working resource undefined? The postcondition for UNCHECKOUT is that the working resource is deleted. Why not allow DELETE to do the same thing? In fact, why bother with UNCHECKOUT at all? Will leaving this undefined cause interoperability problems? In a workspace context, an UNCHECKOUT does more than delete a working resource ... it replaces the working resource with a version selector whose target is the DAV:checked-out version of the working resource. 5.8 COPY of a version should never create a version selector. Or we should allow servers to specify if COPY or PUT may create initial versions of new version selectors or not. COPY of a version selector should fail. This allows a server to say that all resources in some part of the URL space are versioned, so whether you COPY or PUT into that space, a new version selector is created. I just noticed that I neglected to have an advanced versioning COPY postcondition stating that the new version selector MUST have a new history resource created for it. I'll add this. 5.9 MOVE of a version selector should fail. Then how would I rename a version selector? (Perhaps you're thinking of a MOVE of a history resource or a version, which I agree MUST fail). 5.10 Why can't a LOCK request specify a Target-Selector? Wouldn't this be the usual case when using labels? How would this be semantically different than locking a version through any other means (a version URL or by using the default target)? It's not that it can't specify one, it's just that the result is undefined. In particular, we didn't want to get into the question of whether this locks the association of this label with this version (which would be a reasonable interpretation of the LOCK). Why is there a checkout element in the entity request body to specify something that can be easily specified in the request URI or the target-selector? What if the CHECKOUT request URI is a version URL and the checkout version in the entity request body is a different version? This seems redundant. See above. We want checkout to only apply to version selectors, but if we want to allow the predecessor of the checkout to be a version other than the DAV:target version, you need a way to say it. <geoff> For compatibility with workspaces (which only allow checking out a version selector, not a version), the request URL for CHECKOUT must be a version selector URL, not a version URL. </geoff> I don't understand. Why is the version URL in the request body then? How is this different than having it in the request URL? You need to know the version selector being checked out, but you can supplement that with the particular version you want checked out. DAV:checked-out should be DAV:predecessor-set. <geoff> The DAV:predecessor-set is an optional working resource property introduced by advanced versioning. </geoff> No, its specified as a property of a version in core versioning. The same property should be used for the same purpose for working resources (although it could never have more than one entry becuse there's no merge). I'm not sure what the "No" refers to. I agree that DAV:predecessor-set is a version property in core versioning, but it is not a working resource property in core versioning (i.e. all you are required to have in core versioning is a DAV:checked-out property). In core versioning, the DAV:predecessor-set of a new version created by CHECKIN is inferred from the DAV:checked-out property of the working resource, but in advanced versioning, a server can support a (non-protected) DAV:predecessor-set property for working resources. 6.5 Seems like the Target-Selector header should be able to be used to specify the target in SET-TARGET instead of an entity request body. This would help unify target selection. <geoff> The purpose of SET-TARGET is just to update the value of the DAV:target property of a version selector. It seems more consistent to always have the new value be in the request body, rather than sometimes in the Target-Selector header and sometimes in the request body (you can't put a version URL in a Target-Selector header). </geoff> But this is the problem. You can specify something in a SET-TARGET that indicates what target will be selected by default that you can't specify in a Target-Selector that specifies a specific target. This is inconsistent and confusing. The purpose of the Target-Selector header is to allow clients to easily use human meaningful names (i.e. labels) to identify versions. This is not at all the same purpose as a DAV:target property of a version selector, which is intended to allow you to select an arbitrary version of that version selector. The Target-Selector header specifies a label. The DAV:target property contains a version URL. They are different, because they serve different purposes. 7.3 do we want to introduce a "latest" functor for the Target-Selector instead of using a DAV:latest-checkin-report? Then users can operate on the latest version in a single method. <geoff> The Target-Selector header is currently defined as specifying a label. I believe it is simpler to keep it that way. </geoff> But DAV:latest is a common and useful (although somewhat dangerous) function that we had agreed to include in past versions of the spec, regardless of the simplicity of the SET-TARGET method or Target-Selector header. Yes, and that function is available as a DAV:latest-checkin-report. 7.4 How would the client be able to predict what information will come back from the DAV:version-tree-report if the server can arbitrarily decide which elements to eliminate? <geoff> Why would a client need to know? The version-tree-report contains all the versions, so every successor is guaranteed to appear somewhere in the report, allowing the client to display the tree however it wishes. </geoff> Then I don't know what you mean by the server can arbitrarily decide which elements to eliminate. I took it to mean that a client could not expect all the versions to be returned in the report. Maybe I missed what was being pruned. Ok, I see it now. The "elements" you referred to are the properties of a version, not the versions themselves, and the ones that can be eliminated are ones that may have already appeared. Correct. Section 7: refresh my memory, why aren't these reports just live properties accessed throug PROPFIND? The core reports would seem to be handled just fine this way. In general, we have modeled things that modify the state of a resource (i.e. things that you would expect to modify the "modification date" of a resource) as properties, while things that indicate relationships with other objects as "reports". For example, the "predecessor" of a version is part of the state of the version (and therefore a property), while the "successor" is a report (you can add successors without changing the "state" of a version). In many cases this, is a judgement call rather than a hard and fast rule. I don't quite follow the layout of a version-tree. In the example report, a version-tree contains a version and a nested version-tree which I assume represents the predecessors of the version. But there's also a predecessor-set. Isn't this redundant? The nested version trees are the "successors" of the version. This is the inverse of the predecessor-set relation. 8.1: Doesn't core versioning need the concept of a History resource too? Isn't that what's returned by the version-tree-report? Yes. I'll move this concept into core versioning. Core versioning should be (able to be) defined as having a single, default workspace with no ability to create new workspaces. In a workspace, a version selector is replaced with a working resource when it is checked out. We didn't want to require this behavior of all version selectors (just those in a workspace). Wouldn't activity be used to label the arcs between the versions rather than the versions themselves? That is, the activity names the line of descent used to create a logical change. When a version has multiple predecessors, it would be misleading to label the arcs, because this would seem to say that multiple predecessors of a version would be on the same line of descent. Fork should be in core versioning as it is possible to create them there. We don't support any "fork" properties or methods in core versioning so there's no need for the term until advanced versioning. 9.1 So a workspace appears in the user's namespace, not as an identifier specifying what version of a version selector to select? Correct. A workspace can of course appear in a Workspace header. This section is not clear. Paragraph 2 needs more. Section 11.1 makes it clear. A little moreintro here might make the document read better. Perhaps you could write up a sentence or two that you think would make it clearer? 9.2 the point of baselines is to create a stable version of a workspace so it can be recreated at some later time. All this stuff about efficiency and space doesn't seem to be the point. If all you needed was a stable version of the workspace, you could just make a copy of the workspace (with the COPY method). The only reason for the baseline is to provide a more efficient mechanism for creating and storing many copies of large collections. 9.3 Switch paragraph 1 and 2. Paragraph 3 describes the primary use of activities. Paragraph 1 introduces two unsupported concepts: projects and constrained forking. These first two sentences didn't compute particularly well. Done. Replaced "project" with "team of authors". 9.4 I think we should remove automatic merging. It's only a couple of properties, and it's important functionality that servers provide today. 9.5 public and private are generally used to denote visibility, not life-time. It seems more intuitive that a versioned collection could contain members that are versionable resources and versioned resources. One can depend on getting a particular version of the version selector, but the versionable resource contents may change. It seems like we're mixing concepts here. I agree that the terms public/private should not be used here (I'll rewrite the section without them). But I believe that allowing someone to checkin a revision but not allow them to count on being able to reliably retrieve the value of what they checked in would be the more damaging mixing of concepts. The fact that some of the members of a collection reference versionable resources doesn't seem to have anything to do with its membership in a collection, versioned or not. We need to think this one out some more. If something is not under version control, saying it will not show up in versions of the collection seems both reasonable and expected to me. 10.2.4 indicate that the user would have to checkout the latest version of the resource, and merge his changes in order to recover from such a failed checkin. Not clear how this would be done as it would require two working resources for the same version selector in the same workspace. You just need the existing working resource, but modify its DAV:predecessor-set to reflect what you want to be its predecessors. 10.3.4 What's the relationship between the checked-out and merget-set properties of a working resource, and its predecessor-set? They are three orthogonal properties, meaning different things. The only relationship is that on CHECKOUT, the server must initialize the DAV:predecessor-set to be the DAV:checked-out value. 10.4.4 Where did this come from? It seems unreasonable to have a resource "half versioned". What's the use case? In Pittsburgh we agreed to delete this property, so it will be gone in the 07 draft. 10.5.2 When many workspaces are merged into a workspace, it is unclear which one is it's parent. The parent is just the one that created the workspace, and is not affected by merging. I'm happy to change the name of this property or delete it, since it does not have any semantic properties in the protocol. 10.5.3 I don't think we need parent/child relationships between workspaces. The relationships are in the successors and predecessors of versions in the workspaces. Many systems track the workspace from which a new workspace was created (it's a likely merge candidate, if nothing else). This is very different from the version predecessor information. 10.7.2 dependent-activities better describes the role being played. I'm happy to change what word we use here (I believe that we stopped using the word "dependent" when some folks didn't like the workflow implications ...). 11.1 & 12: I like the way this worked out. Good! 12.2 What are the possible combinations? e.g., can't have baseline without workspace. Is there a hierarchy? There are some dependencies, but most combinations are legal. In particular, at Pittsburgh we decided to make baselines and workspaces independent (you baseline and merge to a collection, rather than to a workspace). 12.3, 12.4: could be an error instead of undefined? We'd like to leave room for later drafts of the protocol assigning useful behavior to these methods, if such behavior becomes apparent. 12.8 Why not have the server create the history revsource as a side effect of VERSION-CONTROL on a versionable resource? That is what it does (unless you specify a history resource in the request, in which case it uses that one). One can get the history URL from the created version using the default workspace. Actually, you get it from the DAV:version-history property of the version selector resource. VERSION-CONTROL needs to take a workspace header to indicate that the new version selector should be in that workspace. It could, but since workspaces are just exposed as regular collections, it wouldn't have to. I had a really hard time getting my head around what's happening here. Too many if-thens with all possible combindations of request URL and version element. VERSION-CONTROL on a versionable resource always creates the history resource and version selector. Other version selectors to this same history resource are created by binding to the initial version selector. There are only two conditions: either you do not specify a version history, in which case a new one gets created for you, or else you do specify a version history, in which case that's the one that gets used. A "bind" would not give you a new version selector, it would just give you a binding to an existing version selector. What's the relationship between the target-selector header and the workspace header? Does the target-selector header override the workspace header? A Target-Selector overrides the DAV:target property of a version selector (whether or not a Workspace header is used), but does not override the Workspace header (i.e. the workspace URL in the Workspace header is prefixed to the request-URL, whether or not a Target-Selector header is present). 12.9 first precondition: does this mean that if the resource is already checked out in that activity, then the checkout fails? No, this only says what revision must be checked out. But there is an error here ... this precondition should only hold if DAV:unreserved is not specified. I'll fix this. This used to be the case indicating more than one user cannot be working on the same activity on the same resource at the same time. If this wasn't true, then it would be possible for different forkes of the same version to be checked out in the same activity which would result in a violation of the first precondition? The first precondition is only violated if a non-latest version of a given activity is checked out, which doesn't disallow more than one checkout of the latest version. Multiple checkout of the latest version is disallowed by precondition two (unless DAV:unreserved is specified). If so, does the DAV:checkout-fork apply when using activities? Yes. Whether you are using activities is independent of whether you are allowing or preventing forks in the version history. postcondition 2, it would be nice if this were true for core versioning too where the "default workspace" was "/". This would require that you have multiple workspaces in order to have multiple checkouts from the same version history. second to the last postcondition: ... the DAV:activity. if any, of the checked out version is used. Does that change anything about the postcondition. If the checked out version's activity is empty, using that means that the working resource activity will be empty as well (which is what we want). postcondition 1: don't know why this is different from core. That's the DAV:working-resource-set property? If so, there is no such property in core. 13.1 See comments on MERGE. Merge should take a workspace too, and merge the members of the workspace into the merge destination workspace. Then MKWORKSPACE doesn't need a parent workspace (which implies a hierarchy that isn't there). There are two issues here. Should MERGE allow you to specify a workspace. We have agreed that it will, so I'll make that change. The other issue is whether it is important to track which workspace was used to create another. This was discussed earlier in this message. 13.3 the request URL should be able to be a workspace too in order to merge one workspace into another. Yes. This is now implicit in the fact that you can merge a collection, and a workspace is just a kind of collection. 7th paragraph, last sentence, a new version selector should be created in the destination workspace, and the version included. This would be how new resources are added to a workspace from some other workspace, version, activity, etc. That would cause resources that have been explicitly been renamed or moved to reappear under their old names. This would be a "bad thing" (TM). Last precondition: what if one of the conflicts results in a CHECKOUT failure but others are OK? Is it a best effort operation, or does the MERGE fail? Note that the user could fix the problem with the checkout and do the merge on that single resource at some later date. Note also that there's no reason to not continue doing the merge from source to destination untill all the conflicts are gone. So it looks like it would be OK to do best effort. Yes, the protocol currently allows "(2xx)- Partial Merge". We need to decide how that is to be marshalled (like 207?). How are version selectors removed from a workspace? With DELETE. 13.4: will this be supported by many servers? Do we need to include it? Is it likely that after unversion on some servers, it will be impossible for them to retain the history resource? I'd probably be inclined to just get rid of this method (UNVERSION-CONTROL) since it could easily be simulated by a client. Great review, Jim! Cheers, Geoff