- 1 Sugar Data Model
- 2 Project Files and Metadata
- 3 UI Decisions
- 4 Examination of Use Cases
- 5 Manipulating Object Containers
- 6 Conclusions
Sugar Data Model
homunq> eben - I want to start coding new activity bundle format, do you have a minute to talk about your UI vision there? eben> homunq: Sure, let's do it.
homunq> Is it worth including enough info to reconstruct "broken threads"? (recall: forks are one case of "broken threads".) eben> I not convinced that broken threads should be reconstructed. I personally feel that a broken thread should be treated as a separate activity. Should the "original version" be an activity on the other side of a break? homunq> The principal reason I think that broken threads are worth it is that they make our security model more in-line with reality and thus more secure - people will have less need to subvert it in order to achieve their goals.
homunq> I imagine that the user has some easy way to explicitly update her favorite version and to explicitly update instances when a "newer" activity becomes available that crosses a break. This is because the newer version implicitly lives within an unbroken thread and you can explicitly say "use the original version" if it is available. I also imagine aggressive backups of activity versions so that if you have server coverage, then chances are that you can get the original version. Note: the original version could not be on other side of a break because the only way to cross a break is to open and opening saves a new version of the instance. Thus only the old instance would have an old original version. eben> I disagree with it on the principle of allowing "just anyone" to create new activites based on existing activities which appear as "new versions" to the rest of the kids. Let's work through an example:
eben> Consider activity A. homunq> A exists in version Ax.1, Ax.2, and Ay.3 eben> right, perfect.
homunq> so you have an instance of Ax.1 and then you get Ax.2. Your instance will now automatically open using Ax.2. eben> now, Bob comes along, guts A and derives Ay.1 homunq> No... the rules would be that version number keeps increasing. Now you get Ay.3. Something derived from Ax.1 is Ay.2 Or in our example Az.2 because y is taken. eben> homunq: But this is the point we disagree on. You say that it increases, because the "identity" doesn't change. I say that it starts at one, because it's effectively a new activity.
homunq> OK. So whose example are we following? eben> Well, I'm trying to contrast them. homunq> I say mine, because the burden of proof is on me.
homunq> So you get Ay.3. Now if you just run your instance, it still runs as Ax.2 but it has an extra button in the journal called "update me". eben> Ay.3 did not get auto-favorited, even if Ax.2 was already favorited. homunq> The palette or something on that button says "Ay.3 claims to be a newer version, but I cannot be sure" - some message that conveys the alleged nature of the relationship.
eben> OK. Is there a need for this button? Couldn't the kid just manually choose to open the instance with Ay.3 if they choose? homunq> Favoriting and instances are two different (but related cases), I'm talking instances right now - but yes, they could do it manually. I just think it's nice to have the button.
eben> And why do you think it's safe to tell the kid that this is a "new version"? homunq> I think it is safe to say "claims to be a new version" homunq> Note: eben> How does it claim this? homunq> implementation detail
eben> Does the activity retain the same service name? homunq> No. eben> It has a new service name? homunq> The service name is not user-readable. It can have same or different user-readable name. However, it has a list of previous service ID's and version-of-forks.
eben> Who cares if it's exposed? In your model, does Ay.3 have the same service name as Ax.2? homunq> No. The identifiers you call "service names" are associated with "unbroken threads". They change across breaks.
eben> How is it proper to suggest to the kid that something with a) a new author and b) a new service name is a "new version" of something they already have? For that matter, how is it fair to the author of Ax.2 if anyone out there can come along and push (via suggestion) a "new version" out there which may be totally different, or buggy, or corrupt? I think that activity thread deserves to have a sense of ownership associated with it. homunq> I think that it is perfectly fair, if you give users explicit choice. eben> No, I don't think that's fair at all. You might get away with saying "Here's something (Ay.?) that claims to be an *alternate* version of the Ax.2 you have been using"... homunq> I think that people sometimes want to assert that and sometimes have good reasons for wanting it without having good reasons for getting the x signing key. eben> Saying that something is a new version implies a chain of trust to me, and an authorship, which doesn't apply in this case. That's why I personally like calling it Ay.1 (The first version of an alternate thread), even if it was based upon something else. homunq> Then what about Az.1 which inherits from Ay.1? How does it say that Ay.1 is a later ancestor than Ax.2? That is what the monotonic versions are for.
homunq> There is another bit I have to explain. In my model, there are private instances. Any instance marked private cannot be opened by an activity which has P_NETWORK unless it has the same service ID as creator. eben> Any instance that has not been shared?
bemasc> The key thing here is that Eben is also proposing that instances be explicitly mime-typed. Furthermore, the type of an instance created by "Ay.2" is not "Ay.2"; rather, it's "xml/tamtam-projectfile". Then, if you change the format in an incompatible way, then you should introduce a new "mime type" to describe the new format. (possibly not an actual "mime" format, but some kind of project file with type).
homunq> Is there any support for format versioning in mime types? In particular, how do you define "incompatible"? eben> I'm not sure... do we need full ancestry across threads? If one thread simply uses monotonic versions and full ancestry internally, and perhaps also includes the thread it forked from, do we really have need for more?
homunq> This is a problem for me. If you add a new bit of data that does not break the old activity, but is not supported by it, how is that indicated in mime-type-land? bemasc> If it breaks the spec for that filetype, it's a new filetype. That's the author's decision. eben> Incompatibility certainly comes as a responsibility, in my mind, of the author of the thread. homunq> I think that most format changes are in the grey area of compatibility. bemasc> That's why it's the author's decision.
Types vs. Inheritance
eben> Consider taking Ax.2 (because you love the interface) and on purpose explicitly swapping out all of the data formats/protocols used for your own. This is a case where, clearly, each thread can stand alone, but there is no intent to make the two threads compatible with each other... and why should there be? They are authored by two separate people who may not even know each other. homunq> In that case, your new activity is not a child version. eben> I claim that this decision can only be intelligently made when you restrict the scope to a single thread. homunq> Exactly, stand alone.
homunq> Sorry - we are talking about two things - mime type and activity ancestry. I do not want ancestry to be an archeological record of code origin. homunq> If you change file formats incompatibly, then you should start a "new activity", even if it has same user-readable name. bemasc> Ancestry does not imply compatibility. Witness MS Word. Conversely, witness AbiWord, which is by no means descended from MS Word, but (relatively recently) got .doc import capability. The question is: what can ancestry tell us? Alternately, what actions can the system take on the basis of ancestry? You seem to be proposing one action the system can take on the basis of ancestry: determining which Activities are capable of opening which files. Another action the system can take is inheriting permissions. After some discussion at the "mini-conference", there was some consensus that if a future version of Activity is signed by the same key, then it should inherit the user's permission settings for that activity. homunq> Correct on both counts. I also think that the shell should give the user a prominent option to open old instances with the child activity.
bemasc> I still prefer explicitly typed instance formats. homunq> Explicitly typed but not versioned? bemasc> If you've broken compatibility with the previous versions, you should declare a new instance format (or increment your version format number) homunq> mime types have a version number? bemasc> you can just add a number on the end, if you want. bemasc> I think formats should be versioned entirely separately from the activity bundle itself, and possibly with no assumption of backwards compatibility.
eben> So activities that break signature, you agree, have new service names, do not automatically receive the same permissions, what else? I still fail to see an argument for treating it as a "new version" in the same thread. It's effectively a new animal. bemasc> homunq wants to use a non-secured ancestry system to determine instance compatibility. This amounts to declaring that the type of an instance is the specific version of the activity that created it. Then another activity can declare "I can open that instance" by listing that activity version as one of its ancestors. homunq> I also want it because I think that if we do not provide an un- secured (and thus un-trusted) mechanism, then I think that developers will feel undue pressure to use the trusted mechanism in inappropriate ways.
eben> Wait wait....I find your last comment disagreeable, bemasc. If the type of an instance is 1-1 with its (activity,version) pair, then we don't have any kind of cross activity compatibility.... bemasc> In homunq's proposal, Activity B.8 can only read something written by A.3 if B.8 lists A.3 or later as an ancestor. Also, we can have that A.10 is a direct descendant of A.3, signed with the same key, so it should inherit permissions, even though format compatibility has since been broken. eben> That seems arbitrarily limiting, no? homunq> Note that multiple inheritance is possible. Also, Ay.10 can say "I save in format Ax.3".
bemasc> Conversely, in eben's proposal, instances are handled just like files, in terms of typing. Thus A.10 can declare that it only reads a certain instance types, and the type written by A.3 might not be in that list so then activity A.10 might not be able to open instances of A.3. eben> What if these activities have no idea each other exists, but they share a common format? They should "just work", and the system should know that they can handle each other's formats. bemasc> eben: I agree, which is why I prefer your proposal. Also, homunq's system can be implemented easily inside eben's.
eben> It seems absurd that a simple activity that writes a text file could produce something that can't be opened by any other text editor created in the past or future. homunq> Of course. That is why I keep saying "actions are not files". The text file can be opened by any text editor. "I emacsed that" and "I wrote that" are not interchangeable but the resulting text files are. eben> Instances with all associated metadata and goodies? I guess we haven't ever had the notion of an "instance type" to be honest.... bemasc> That's because we haven't had a distinction between files and instances. homunq> In your new journal spec with actions, the difference is much more clear.
Project Files and Metadata
What is an instance?
eben> Thinking about it, the whole idea was to treat the instance as having the type of the "primary file" object, such that one could say "open with X" and it would simply open that file in the new activity. homunq> That makes no sense to me. An action can have multiple, incompatible files associated. bemasc> You imagined a scenario in which each instance was associated with a "project file". eben> Yes. I think each instance will have a "project file", and that project file will have a type. In my head though, that type was TXT or PDF or PNG or HTML.... bemasc> Aren't TamTamEdit's project files are going to be some complicated custom format?
homunq> Also, in my head, the instances/actions had some of their format in metadata - or is that abusing metadata? bemasc> I think metadata should only be things that the user is invited to mess with eben> Sure, that's fair... metadata was to hold the state data which does not fit into the "well known file format" assuming there is one, or which the author doesn't feel is a necessary part of their new file format if it's not a known one already. homunq> What about things like screenshots? Changing it could be a security hole and I can't think of a positive use case. bemasc> Changing the screenshot won't screw up the instance. My rule of thumb would be, "the user should be able to write and delete metadata arbitrarily and at random without screwing up the instance when it resumes". homunq> bemasc: that is a fair rule.
eben> So, in my head at the time, the point of separating the actions from the objects was so that the metadata *could* hold the "extra" stuff, and so that it *would* be possible to say "open this instance with some other activity" because the file associated with that instance would be just a well known format of some kind. bemasc> project files are almost always application-specific. The example in my head is Audacity. eben> I think that's about a 50/50. In the case of an Audacity instance... bemasc> Audacity uses an XML-based project file format to describe the project itself, and also stores bits of audio in another directory that has like 1000 little audio files in it eben> only audacity (right now) can read that file (even though others could read, for instance, the samples used or the rendered output of it). But, there still is a file, and it still has a format, and other activities could certainly adopt it in the future. bemasc> the project file format is specific to audacity, and is occasionally changed in a non-backward-compatible fashion homunq> good example. that stuff clearly is not metadata despite what eben and I vaguely thought.
bemasc> So the question, for me, is UI. If someone writes an Audacity- compatible Activity, what should users do to continue their work in this new program? Is that an example of resuming your work, or an example of starting a new instance?
eben> It would be prudent for the creator of that format to keep all the necessary data for the project inside it, and to save other info (perhaps UI hints about the selected tab, the current view settings, etc.) as state metadata. homunq> why not keep the tab in that project? eben> Because that info is specific to the UI of the activity, and the platform that the activity runs on. eben> I have audacity for OSX. It doesn't have tabs. It probably has a completely different and perhaps incompatible UI.
homunq> OK, so actions have 4 kinds of data: files, projects, view settings, and genuine metadata (tags). I'd rather not assume that any of those are equivalent. If an activity author wants to assume that, fine. eben> I actually see 3 myself: associated files (of which one is the project), state blob, and metadata. In practice, the state blob might be some piece of inaccessible metadata. eben> Consider a painting program. Clearly you want the "project file" to be simply an image, for the best portability. Storing the currently selected color would be metadata. (This, too depends....for instace, if an SVG editor decided to support .ai instead of .svg, then the color would be stored too, perhaps, as part of the actual project file....but that's all dependent upon the standards in place, or being set up in the case of new activities.) homunq> "Inaccessible" is the point. This is different in some key way from normal metadata. The implementation can be the same though.
bemasc> What about undo history? eben> That would be part of the state too, right? bemasc> Well, that's the question. An image editor clearly doesn't store the undo history in the image. bemasc> (or does it? the PSD format stores undo history, I think, and so does gimp's XCF)
homunq> in a perfect world, undo history would be in olpcfs ... bemasc> homunq: I agree. homunq> I'm actually kinda serious.
bemasc> I'd like to work from the UI down. As a user, I go to an instance and click "resume" or whatever. What happens? Am I shown a list of activities that can resume this instance? homunq> There is a "just resume" button: you click it, it defaults to something. If you hover over it, it gives you choices. eben> (It resumes with the last activity you used for that instance.) bemasc> If there's a new version, does it use the newer version? eben> bemasc: I would argue yes, if it is part of the same thread. homunq> (If there is a new version AND the new version can open that data). It seems that the data has a master file which gives it its format?
eben> Another potential option is to say that it uses the newest starred version, if there is a starred version in the thread, or the most recent otherwise. (again, assuming it can.) bemasc> What if there are no more activities installed in the thread, but there is another activity installed that can resume it? eben> In that case, we probably (currently) pick the next in the list. bemasc> what if I want to resume with a non-default activity? (or a non- default version) eben> A better solution would be to present a modal dialog presenting the available options, including the option to attempt to recover the activity which created it. If you want to do that you use the secondary palette of the resume button, which lets you choose anything that supports the type. bemasc> That all sounds pretty reasonable to me. eben> One option for the non-default version case is to say that the list is actually hierarchical (one level). If there are is more than one version of an activity available, it could yield a submenu of the options, and indicate which of those are starred as well.
homunq> I have a problem with that: what if you have 5 versions in the same thread? Do they all clog up that list? eben> No, the versions that are in an unbroken thread are treated as "one thing" until you ask for more info. This is the same as what I intended to represent in the activity list in home. They would be grouped by unbroken thread. Ax.? and Ay.? would both appear in the top level list, side by side (well, depending on sorting...but assuming they choose to keep the same readable name).
bemasc> It sounds like the system has the following: each instance is a collection of files, one of which is declared the "main file". Each file has an explicit type. Each instance has "application metadata" and "user metadata". The application can use application metadata as a convenience to store a small amount of simple data that is some how "not worth" putting in a file. eben> not worth or not appropriate (in the case of trying to adhere to already defined formats)? homunq> There are several issues this does not address... what if format tamtam-project5 can be opened imperfectly by tamtam-project3? Obviously tamtam3 cannot preemptively say this. What if different subfiles have different levels of privacy? (I am thinking about private signing key for an activity bundle.) bemasc> We could allow files to have multiple types. eben> In the worst case, TamTam5 could include a way to export a TamTam3 file/instance bemasc> Another solution (for a paint program) would be to have the instance contain "image.png" in PNG format and "mysettings.paint" which is a JSON file with activity-specific settings. Then make image.png the project file. eben> instead of the state blob as metadata? bemasc> yes - the "activity metadata" could easily be stored in a file other than the project file, without breaking compatibility eben> I think the goal is to prevent those kinds of "junk" files from accumulating, since the kids can also browse the objects as well. That's not meaningful as a file itself, to the kids. bemasc> JSON is fairly human-readable. We could also adopt a "dotfile" convention like the one used in all UNIX systems. eben> Well, sure, but in the interest of making it easy to browse through the objects one has created, seeing ever other one being a settings file would be obnoxious. bemasc> Hiding things from the user is generally bad, but the "activity metadata" would be hidden from the user anyway. eben> My point is the Journal has to add knowledge for that type of thing, if we do that. bemasc> yep, but the alternative is that the datastore has to handle an additional metadata system eben> well, does that depend, too? How is it settable? If we don't expose it in the UI, does it matter if it's just normal metadata? bemasc> well, then the Journal has to have support for knowing what kind of metadata to show. there's no way around writing code for this stuff
homunq> What if I have an tamtam5 instance and an app I like which opens tamtam3, but I do not have tamtam5 activity. eben> That is a *really* tricky question....it's part of the reason that we didn't use aliases at all in the past...
bemasc> (this, by the way, sounds a lot like Core Data) homunq> I read the wikipedia briefly, I could not tell if it was some way to keep undo stack, a layer above SQL, or what... bemasc> it's a generic high-level data storage system homunq> definitely has some relation to what we are talking about, but not clear if it has the answers. that is not the problem we're solving right now.
bemasc> eben: I think we're pretty clear on this. Develop can implement homunq's semantics over a simple per-file type layer and the Journal just needs to know which of the files in each instance is The Main File homunq> Does the main file show in file list or just in actions list? eben> It's just an ordinary file - the main file might just be The Image, or perhaps The Text. bemasc> "The Main File" is the "Project File". It's the file that defines the instance. homunq> there seems to be confusion. if you have two files, one of which is a project and the other is a text, then I think the project should not pollute the files view
Examination of Use Cases
eben> consider Record. You take 10 photos. You get each photo as an object. You get the "roll of film" as an object. The roll of film is the project file. It seems equally valid to send the whole roll to someone, like an album, as it would be to send one photo. m_stone> hang on there. the roll of film is more usefully regarded as an "object container", i.e. a set or list of objects. we really want other people to be able to process such containers. eben> sure, in this case it is nothing more. In other cases, the container may have a bunch of other data which talks about how to put together the things it contains. m_stone> however, there's a lot less value in them building support for parsing records of Record-37's graphical state when it was closed. for sake of argument, call the latter the ui continuation. bemasc> right, and that's why the roll of film is the Project File for this instance. that's why I'm suggesting that non-critical state be put in a separate dotfile eben> right, a hidden file, or in metadata....but yes....all state not appropriate for the objects themselves goes elsewhere.
m_stone> Please see the picture and descriptive paragraph at the top of http://wiki.laptop.org/go/User:Mstone/Bundle_commentary. Then, please use the already documented terminology until you demonstrate that this terminology is inadequate. (though please comment inline in this page and sign your comment if you think I left out something important). eben> where does metadata/state live in this diagram? As "instance"? m_stone> UI state lives in the "instance" node. m_stone> give me some examples of metadata? eben> well, two flavors of it: creation date, participants, tags, description, activity specified metadata such as number of pages, etc. Then there is state metadata for the purpose of recovering the instance (the UI continuation part) m_stone> I tend to think about the problem relationally because I anticipate objects (and object containers, which might themselves be objects; I'm making no commitment here) being referred to from several of these action graphs m_stone> so I would say that the action has a set of time periods when you worked on it. likewise for the objects.
homunq> OK, sorry, I need to go back for a second. I agree with the decision of this conversation that there is no UI-necessary information in version history, that is not in "what actions can I open". However, I still like version history because it is compatible with the model of forking versions of an arbitrary object, not just of an activity. My feeling is that the journal UI should support this forking-version model in some way. homunq> OK, it was good for me to say that - it made me see that they are separate issues.
bemasc> really? I thought we were going for copy-on-write semantics. eben> that's true in general but in practice, it's complicated. Consider a Journal entry which is just an action "you sent file X to your friend Y". That's an action which references X, but does not copy it. In fact, it's not a write. But that doesn't mean that we won't have multiple actions referring to the same object (actually, version thereof) bemasc> Then we shouldn't say actions=instances anymore. I would argue that that action does not have any instance associated with it. m_stone> depends whether the action is resumable. actions which can be resumed have instances associated because instances are the actual material which permits resuming eben> which is why the graph m_stone pointed two has those three nodes in a little triangle and why the bundle (needed for resuming) is a child of the instance. m_stone> however, even though I can't resume the (completed) action of sending (A,B,C) to Z, I still want to be able to snag A, (A, B, C), or Z... bemasc> I think that makes sense, so the action should retain pointers to the appropriate objects
Grammar and Criticism
bemasc> what we have further been proposing is that each instance refer also to some specific object as the Main Object m_stone> and, at face value, that sounds nuts. (though perhaps I haven't understood your use case or your design) bemasc> the use case is determining which activities are capable of resuming an action m_stone> resuming an action? perhaps you meant 'processing an object container'? bemasc> I'm speaking from the user's perspective m_stone> don't. one makes a new action, the other doesn't... apologies, the "don't" was a visceral reaction - a segment of "your statement does not typecheck"
eben> we meant 'resuming the instance'. The question is: "which bundles, apart from those linked to the instance within a given action, could be used instead if desired?" bemasc> Suppose I've just used Record to take 10 pictures. I now want to view them in a gallery that understands Record's photoset file format. How should we think about this? m_stone> (perhaps because it's a standard List format used throughout Sugar...) bemasc> one option is to offer a number of activities that can resume this instance m_stone> I say: "You View the photoset." m_stone> That requires finding a Viewer (an activity), instantiating it and telling the instance to process the photoset, and recording the action of Viewing. (Recall that Activities are usefully regarded as prototypes of instances) eben> right, so we're talking about how to "find the viewer"
bemasc> the broader question is: when do we resume instances, and when do we open files and thereby start new instances? We are trying to come up with a way to make this determination. One suggestion is that each instance should identify one of its files as the "project file", and any activity that can open this file can be shown in the UI under "Resume with..." m_stone> I see two formulations. I don't yet have a strong preference between them. a) Activities can be used to synthesize instances ready to process some objects. It's just part of what Activities are. so we might use this ability to get an instance attached to our roll of photos which we can "sume" for the first time (since we're not really RE-suming it...). ;). The other option is to say that Activities can be performed on objects and that this creates an Action which, just as a quirk of activity implementation, probably has an instance associated with it that can be resumed. bemasc> I don't understand, as usual. Do you mean Activities can be performed on object containers? m_stone> I mean that the shell should understand object containers for me so that I can Paint on individual photos from a roll of photos of butterflies that I Recorded yesterday.
m_stone> eben: have I lost you as well? eben> Only inasmuch as I don't know what point you're driving at with the example. m_stone> I'm saying that "resume with" is either nonsensical (because instances resume and do nothing else) or that what "resume with" should mean is "use <___> as a prototype to make a new instance which, when resumed, will be attached to objects <---->" since activities are logically quite similar to prototype instances in that they offer some fixed UI continuations which can be combined with zero or more objects. (i.e. they tend to have a default "initial UI" that they use when instantiated.)
bemasc> "resume this instance with Activity A" literally means "start Activity A and tell it to open this object container" m_stone> resume this "instance" with activity A? According to my grammar, you should mean "resume this instance|". bemasc> I do not support your grammar. m_stone> The "with acitivity A" seems nonsensical. Instances are not parametric over activities. bemasc> they are if we decide they are. m_stone> why is the resulting UI a good one? bemasc> mostly because we have no distinction between object containers and instances in the UI eben> agreed with m_stone regarding "resume with" being the wrong speech for the intended meaning of the operation. We considered "as activity A" instead...
Manipulating Object Containers
bemasc> the question is really "what should resume mean from the user's perspective?", and I think the answer is "I want to keep working on this abstract project" where the abstract project is concretely represented by an object container, not by any particular activity. m_stone> totally agreed. however, "project" should concretely mean "crazy UI data that I never expect anyone else to deal with" rather than "useful group of objects which lots of other things can deal with". eben> Actually, project in his meaning was "the file which describes what to do with the useful group of objects" m_stone> a simple collection of objects does not innately specify an activity I can use for processing those files. eben> That's the point of the "project file" in the first place. There *is* something that takes on that role. (And which advertises it's mime-type so other activities can be instantiated from the objects.) m_stone> note: an instance is navigable to the activity that is its prototype. that way, if I want to have another instance of recording on "fish" instead of "butterflies", I can get there from the instance associated with the action of recording butterflies. However, I'm not connected solely to Record from the collection of objects. In fact, if Record has no photoediting capabilities, I'm might not ever find it adjacent to the photos in the UI. eben> each instance has "a collection of objects" associated with it. one of those is flagged as "the primary object", such that other activities can be instantiated with it as necessary. The primary object knows what to do with "the collection of files"
bemasc> Suppose I write a webpage using the Dreamweaver activity. It's a collection of files, with one HTML file but also CSS and jpeg's. Then I decide that I want to view it in the Browser. then I decide that I want to edit the CSS by hand in a text editor and then I decide I want to open it with dreamweaver again. first: how do I open the webpage with Browse? m_stone> you've got tree-structured data. All of our "object containers" to date can be represented as plain old directories. bemasc> right, but how does the Journal know that Browse can open this object container? eben> I don't think that's true. the photos example is a case where the container is empty apart from its contents.... however, an HTML instance might have several images, a few sounds, and a video in its object collection, with a HTML file treated as the "object container", including the necessary code to put it all together. You can open the HTML file in the Dreamweaver activity again if you want. You can open it with Browse which will know how to display it. You could open it with SimpleWrite, which would ignore the other objects and just show you the source code. bemasc> but the HTML file alone will not open correctly in Browse, and this is my key point
m_stone> I suggest you draw some labelled graphs of the progression of data through your use case. it will be much easier to discuss specific diagrams. bemasc> I am much more interested in working from the user's perspective m_stone> then draw your diagrams from the user's perspective first and translate beneath them into the dataflow perspective. begin the action of Browsing the Web-page. bemasc> So which button would that be? what should a user have to do, after having put together a webpage in a creation activity, to view it in the Browse activity? m_stone> I'm sorry, but text in IRC is not cutting it for me. I'm just not understanding what you're getting at. Please provide a diagram, or adapt my diagram and show where the fault occurs. bemasc> I cannot diagram this m_stone> can you write a paragraph instead?
eben> why wouldn't it open in Browse? bemasc> because the HTML file is missing the CSS and pictures. so it might open, but it would be missing lots of pieces. eben> no, all that stuff is contained in the "useful objects collection" of the instance, right? bemasc> Browse needs to be able to open the whole "object container" eben> Why shouldn't browse be able to reference these? bemasc> because HTML refers to images by paths, but those pictures won't even be visible in the filesystem to Browse eben> Why not? If not, how are they even accessible to Dreamweaver when you resume it!? eben> If I have an HTML file and an image on my Desktop, the former referencing the latter, and I open that HTML file, it will work fine. What's the difference here? bemasc> the difference is that in this case, that image won't even be in the filesystem as seen from the perspective of Browse. activities can only see the specific files that they have been told to open. eben> That's the whole point, here, right? Store the objects out individually so other things can use them, but keep the references so that things work with respect to instances. bemasc> you can't modify the HTML file to include references, or it won't be HTML. so instead, we create a "container" bemasc> I imagine it as a .tar file containing the HTML file, the pictures, and the CSS eben> :-/ Then what good is this? bemasc> if you open the .tar file with Browse, it works bemasc> because it has all the components bemasc> if you open just the HTML file, you get just the HTML file eben> But the tar file doesn't have type HTML bemasc> but it does, because we designate the HTML file as the "project file" for this container eben> No, if that were the project file, then that's what would open with Browse. bemasc> Browse advertises the ability to read HTML, and this .tar file is listed in the datastore as containing a project file of type HTML so the Journal offers the user the ability to open this .tar file with Browse eben> So you're proposing that every "collection of objects" is a tar file instead. when the user accepts, the datastore unpacks the tarfile into Browse's directory and then points it at the project file, which is HTML bemasc> not specifically; there are many other implementations eben> You're talking the technical side. The user doesn't know this was ever tarred. They can still see each, and interact with each object. m_stone> he's just saying it to give your mind the flavor of the packaging-of- related-stuff-together. The Browse-displaying-website example is really the "interact with this html file in the context of this larger collection of stuff"
"Act on ___ with ___"
bemasc> right, but interacting with the HTML file itself is very different from interacting with the whole collection of files. Context is key. eben> indeed! but, this poses some problems for the UI.... consider a Journal entry for this instance...this HTML instance. It might read: "Today you created This_HTML_File, which contains Image_1 and Image_2". Now, the way to resume this directly is to click on This_HTML_File. One would expect clicking that to resume the instance....not open it independent of the images. What, then, if I hover and wait for the palette to appear, to do "resume as" (or whatever we call it)? m_stone> eben: "act on ___ with ___" m_stone> I agree that Browse can use some hints. But I think that Browse _has_ to be able to deal with non-hinted material because it's certainly going to encounter it both because of design changes and because of dumb media like USB keys. I tend to think of the hint as an xattr, keyed by mime type, attached to the top-level dir representing the container of stuff - i.e. it says "dear people looking for HTML - start looking here; love, the Dreamweaver activity" bemasc> if you choose to resume the action with Browse, you get all 4 files and the webpage consists of a combination of all 4 files m_stone> bemasc: ARGH. be grammatical. "if you choose to act on all four files with Browse, you want to get a webpage full of pictures and CSS." bemasc> alternatively, if you choose to act on just the HTML file with Browse, you'll get just the text, no formatting or pictures. if you choose to act on just the picture with Browse, you'll get just the picture. and you can't open just-the-css with Browse, because it doesn't support that type.
eben> back up a step. "choose to resume with Browse"... how do you do that? bemasc> I'm actually not sure, because I don't see any way to resume an action in Designs/Journal eben> My point here is, looking at the mockup, "Rain Forest" is the "roll of film", and it is likewise the Project File bemasc> in other words, the project file is hidden eben> Well, right. The main point to recognize there is that the instances are represented as the activity icons. The objects are thumbnails (or a similar treatment, as seen in object view, which contains the activity icon on a "page") m_stone> my suggestion is that you pull the representation of the object container (holding the four objects) [sic: dir holding four files] onto the Browse activity. Or you select Browse from the list of activities to act on this data with, (where we suggest it either because of an explicit hint or because we suggest all activities which can process any file contained in the group) bemasc> or one of the pictures is designated as the project file eben> The intent was to make resuming an instance as simple as clicking on the primary file which represents it. Of course, each object (including the primary file) has a little "details" button next to it, which takes one to the detail for the object (independent of any instance at all) for acting directly on the object itself.
m_stone> that's a really bad design. you're going to want more than one of them. bemasc> I don't know what you're referring to. I'm just attempting to figure out what's going on in slide 2 m_stone> I'm saying that the idea of "a single designated Primary Object" is folly. bemasc> it's necessary m_stone> for two reasons. 1) because you're going to want more than one of them. 2) because you can't guarantee that it will exist in the presence of dumb media. in my opinion, you have no choice but to design a UI which does not depend on their existence in order to function. (you should, however, design a UI which takes hints that it can find) eben> in dumb media, every "instance" is associated with one and only one object. What does it mean to want more than one? Doesn't that just imply you have two instances? m_stone> take the web-page example. it has some html, some css, and some photos. maybe you're lucky enough to have AwesomeEditor [etoys?] that handles all three. however, in practice, you're likely to want to mix and match. right? eben> m_stone: mix and match in what sense? One could "open" any of the objects independently. m_stone> but some of them must be opened in context in order to make sense. (an essay containing labelled diagrams is an easy example.) but let's go with the web page for the moment. bemasc> the abstract "Webpage" consists of all 4 files. If you want to start an activity instance to view the webpage, that single instances needs to have access to all 4 objects. so one object = one instance won't work eben> in what context? Either I care to look at the collection as a whole, for instance, in Dreamweaver, or I care to look at a single object from the collection. bemasc> the problem is, the UI has no way to open a collection (that I know of) eben> But you just got through proposing the tar approach for getting around that internally bemasc> sure, but I'm talking about in the UI. the only way one ever opens a collection, in the mockups, is to "resume" an activity
eben> The only way to *use* the collection of objects is to do so from its corresponding action entry, naturally. In these designs, the implicit assumption was that the "primary object" served as a standin for the instance itself, which when clicked on resumes the instance. In the same manner, that object would be the thing which had a "resume this instance as activity X" option in its palette. In other words, the representation of the primary object in the design is *as* the instance... m_stone> eben: how do you mean? consider turning a roll of photos into a slideshow. bemasc> you mean a stand-in _in the UI_. I hadn't thought of that. but every object can be opened by other activities. so one object can be opened or resumed, and these mean different things? eben> so there's a hole in the system, right? You can act on that thing either as the instance, or as the object. So maybe that's busted. Maybe we need to in fact represent it "twice" in the UI. Maybe, for instance, that slide should also have a "Rain Forest" *object* down below, with a preview...(a contact sheet, let's say, with the 4 images on it) bemasc> eben: what I want is a way for the user to open a collection. Currently, collections are only represented, as actions, so I've been using the word "resume" to refer to opening a collection eben> currently, meaning in the designs we're looking at, right? bemasc> eben: yes
m_stone> well, how does the photoroll -> slideshow example work? furthermore, suppose I resume the action of photographing butterflies. Presumably, the next time I edit my slideshow, I'd like to be reminded that there are new butterfly photos. (and, in future work, pay attention to changes made to that collection [or to new versions of it that appear, etc, etc]) eben> Right, as an aside, another missing component of the current design (a big one) is that there is no way to say "show my all versions of this instance". The current design only really has versioning for objects, not instances. m_stone> don't you mean 'for objects, not _collections_'? at the big Journal meeting w/ marco, tomeu, bertf, &co. we definitely discussed being able to use collections as part of several actions. eben> Ummm, I don't know? I mean, if I resume an instance 5 times, make changes each time, and then want to see the chain of actions I took to get to where I am.
bemasc> it depends on what the metaphor is. let's not forget the problem of figuring out which version of an activity can resume an instance, which is how this conversation started. m_stone> (a problem with at least one easy solution, namely, to regard instances as executables derived from some prototype...) eben> I feel like we've gotten about nowhere in an hour. m_stone> we had a nice synchronization of terminology. we know of a use case - record butterflies, make slide show, record more butterflies, update slide show - that it's not quite clear how the present design would represent. eben> Perhaps we need to have an in Cambridge meeting to resolve all of this, going through the posted Journal designs and hammering it until we have a solution for all these issues. bemasc> (I thought you guys already _had_ this meeting, 7 months ago) eben> We did. It resulted in the mockups you see. Which still aren't perfect! m_stone> they don't need to be perfect. they've already allowed significant progress. they're mockups for a reason! :)
m_stone> we also have the "make website - view website - edit images - edit html - view website" sequence. and the thoughts derived from consideration of that use-case, namely, that our UI will work much better if we attach some hints to collections but that we cannot rely on the existence of these hints. eben> right, both of those use cases are not covered, at present, by the design. Mostly because we don't have aliases/references in that sense at all. m_stone> so we should explain that clearly on the design and send some email so the rest of the world can think about it. eben> certainly, that's my point, and why I think it's worth another meeting to make them better. As an interesting option, by the way, we could consider making the way you act on an object contextual to where you initiate the action from. For instance, if I "open" an image in an HTML instance from that instance, maybe it actually saves "in place" by just creating a new version of that instance, with the appropriate file changed? Whereas "opening" the object from within object view would treat it wholly independently, and use the copy-on- write approach to create a new instance for the changes. bemasc> eben: I think I get it. Interesting... it sounds like it might be easy to break things though. For example, a Desktop Publishing application might record the dimensions of all its images, and fail to load them properly if the dimensions change unexpectedly m_stone> eben: I didn't quite follow that comment and I need to relocate to 1cc anyway. sounds like it's worthing reflecting on though. HoboPrimate> can't the use case of creating a new instance of an object be taken care by copy+paste and/or "Keep as New" within the activity?
homunq> OK I'm back. Just so you know, I think it was a very productive conversation. I definitely think that forking versions in the journal is something out-of-scope but worthwhile. but in-scope, I now see what is needed for activity bundles. The html problem (html stores references as paths) is I think soluble - every "open this" is either alone or in a symlinked directory of the bundle. internally, I think the files would be separate - not a tar -but there would be a way for sugar to create a tar to share with others. in fact, I think it would create a tgz. Honestly, this whole idea is just a few steps short of turning activity bundles into actions rather than objects. The MANIFEST could be the "master file". one missing part would be, where do you keep the private signing key. I think that if you edit the html, the UI continuation will be out-of-date. eben> This issue of "editing subparts with other activities" was never formally discussed, and currently has no solution. I'm not sure what to do with that. m_stone> first, write that it exists. Then, spend a few days thinking about it. It may turn out to be nothing more than "future work". eben> I've thought about it at length, without coming to any meaningful conclusions. m_stone> don't give up. you'll work it out. (with help from many others, I'm sure) eben> It's a complement to the problem of "embedding an image in a Write document, editing that image in Paint, and later updating the version in Write automatically". And it also boils down to the copy-on-write vs. reference debate.