Misadventures with gnome Javascript

I recently updated pocket-lint to require gjs instead of seed because the latter has been 100% broken for 6 weeks. The best thing I can say about this experience is that I am very happy there are two competing implementations of GObject Introspection bindings for JavaScript. I am disappointed that the two implementations are not 100% compatible. Most of my changes to pocket-lint were to hide the deficiencies of gjc.

There are small but important differences between gjc and seed that developers will want to be mindful of. Gjs is older, based on Spider Monkey, and servers a simple need: JavaScript is the most common development language, and GNOME should support it. Seed is newer, based on Webkit, and serves subtly different need: I know JavaScript and I want to develop GNOME applications. Gjs works though you might not know it given the lack of documentation, and you might be disappointed to see that it recommit’s JavaScript’s original sin of namespace pollution. Seed is well documented and its extensions are in a separate namespace. Seed’s documentation is 99% compatible with gjs, so I can forgive the oversight. I learned missing crucial 1% of gjs by reading the C source. I was appalled to discover that gjs creates print, log, and argv functions in the global namespace. Seed, being an implementation for developers who really use JS, place the extensions in the Seed object.

I want to use seed, but given that it is broken in Ubuntu Oneiric, I decided to support gjs. I chose to check for the existence of the Seed object, and construct one from gjs when it is not present. The namespace is still polluted. The interpreters have different command lines, though they are similar enough for my purposes.

I think the GNOME community could do better by updating the gjs and seed to share the same command line, and add extensions to a common namespace, such as System. Thus an app that wants to call System.print() will not care about which interpreter is used. This permits developer and distros to choose the backend of their choice. It also lets us change our minds.

PS. I know that some developers want to use gjs to use the JavaScript advances developed by the Mozilla community, but this is a fools pursuit. JS has been fragmented since the release of IE 3.0 in 1996. JS developers know they have to write for a common language, and use libs to provide extensions. I am very aware of the failure of ES4. I hope Mozilla can get its extensions into the official language.

Recovering Ubuntu after an OS X Lion upgrade

I updated my Macbook to OS X Lion over the weekend and had a nasty scare. I could not boot back to Ubuntu, nor could I see my Ubuntu partition. That is the moment where you think, “Is everything baked up? What will I loose?”. I remember that I switched from Evolution to Thunderbird last month; my email was lost. The truth is that everything was okay, and if this happens to you, you can fix this in a few minutes like I did.

I do not know what the OS X installer did. Maybe it resized the partitions. rEFIt did not report an issue. It verified that the the partition tables were synced. Grub did not know about Ubuntu though. I saw the grub prompt (grub>) instead of a message about the selected partition. I followed ubuntu mactel instructions to install Ubuntu, so I know Ubuntu should be on located on hd0,3. I typed:

grub> root (hd0,3)

grub> find /boot/grub/stage1

Find will report if it finds the boot information. If it does not find stage1, then you can try an alternate disk and partition, such as root (hd1,1) or root (hd0,4). When you find stage1 you can configure grub to fix boot:

grub setup (hd0,3)

I restarted and Ubuntu booted correctly. No data was lost.

The reason that OS X could not see my Ubuntu partition was because MacFuse was compiled for 32bit. Lion is 64bit. I installed the 64bit version of MacFuse to see Ubuntu and my data.

Creating a signed release file with setup.py

I recently created https://launchpad.net/lp-release-manager-tools for some videos I am making about how to use Launchpad. One aspect of creating a release is to upload the source tarball and a detached gpg signature verifying it. This is somewhat ironic, since lp-release-manager-tools exists to automate repetitive tasks that release managers do in Launchpad. I really do not like creating the signature. I cannot remember how to do it. I need to read the instruction on the form to upload the tarball each time. So I added a feature to my example project that any project hat uses python distutils can copy to make the signature with the source tarball.

I subclassed the sdist command and added an extra step to create the detached signature of the tarball. I then register the new command as signed_dist. This is the content of my setup.py:

import subprocess

from distutils.core import setup
from distutils.command.sdist import sdist

class SignedSDistCommand(sdist):
    """Sign the source archive with a detached signature."""

    description = "Sign the source archive after it is generated."

    def run(self):
        gpg_args = [
            'gpg', '--armor', '--sign', '--detach-sig', self.archive_files[0]]
        gpg = subprocess.Popen(
            gpg_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

    description="Launchpad release manager API scripts.",
    maintainer="Curtis C. Hovey",
        'signed_sdist': SignedSDistCommand,

A Practical Guide to Bug Triage

Or: “Why I don’t classify bugs as medium”

The process of triaging issues (bugs, features, and tasks) has one crucial principle: Prioritise the work according to need and certainty.

Work is prioritised because there are not enough engineers to do all the work. Some features will never be completed, some bugs will never be fixed. Triage determines which bugs can and will be fixed, which features can and will be implemented. Need is generally understood, when planning work, but certainty is not, and that often leads to wasted work and unmet expectations.

By need, I mean a measure of severity. What percentage of users does the issue affect, and how severely does it impede them from completing their task.

By certainty, I mean a measure of how certain the engineers are that they can address the issue. Time is also a factor in this measure, the longer an issue takes to address, the more likely that the conditions that were first judged will change.

The act of triage is separating work into groups that are being worked on now, next and last. There can only be as many “now” bugs or features as there are engineers. The number of “next” work is limited to the velocity of the engineers and how infrequently plans change. The bugs that are last will probably never be addressed, the last features may never be started.

The corollary to this rule is that there are a finite number of bugs or features in the first two groups. There cannot be more work in these groups than there are engineers to do for the given period of time; otherwise the engineers, businesses and users are being misinformed about when issues will be addressed.

An Example

Consider there is one engineer and two bugs. He can only work one bug at a time. One bug is more important than the other. The risk is that he may not be able to fix one of the bugs before users are disappointed and abandon the application. He risks disappointing all users if he does not fix either bug because he choose the one with the most need over the one he was certain he could address.

If he does not know how to fix the bug with the most need, or that the fix takes a long time, he is wasting time he could have spent fixing the bug with more certainty. The only way he can address the bug with the most need is to employ a hack to reduce the need, to meet the expectations of some users. The hack is also used to gain time to understand the problem, thus increase certainty.

Only Assign Work that You Are Committing to do in the Near Future

When a work is assigned to an engineer, he is committing to complete the work in the near future. What the “near future” means is different for each project. I suggest 3 releases is the “near future”, because when work is planned, the engineer is thinking about now, next, and last. For some projects this period might be 6 weeks, for others, 6 months.

I prefer to plan for the current release, and the next one. As work is reprioritised, it may be rescheduled to the third release. I do not think it is wise to plan a bug or feature to be completed in the third releases because if it slips to the fourth or fifth released, I doubt the it was correctly prioritized as high.

Any high work that is assigned to a engineer for more than 3 releases was not high. If it were, the work would have been reassigned to someone who could complete it in the scheduled time. Any other work that is assigned for more than 1 release is also misprioritised. You are lying to yourself, and the the project’s users, when you assign work that you are not committing to fixing.

Practical Classifications of Importance

Work is often classified in relative terms. It is better to classify work according to how it are managed to convey when and under what terms the bug will be fixed or a feature will be complete. There are three priorities that work can be classified as:

The bug dramatically impairs users. Users may lose their data. Users cannot complete crucial tasks. The feature is needed to encourage adoption or prevent abandonment of the project.

Synonyms: required, essential, now, must do

The work is immediately assigned to a engineer. It is his top priority to fix. Team members help the engineer to plan and do the work. The work is released as soon as it is deployable; in the case of a bug, it is released outside of the release schedule.
The bug prevents users from completing their tasks. The feature provides new kinds of tasks or new ways of completing tasks.

Synonyms: expected, next, can do, should do

The work is assigned to a engineer to be completed in the next 3 releases. The engineer may choose to do other work if he believes it is within the scope of the high priority work.
The bug is inconvenience for many users. The feature provides new ways of completing tasks.

Synonyms: preferred

The work is not scheduled, though it is intended to be completed. When the work is assigned, it may also be scheduled, but there is no commitment to complete it for the stated release. The engineer may choose to postpone the work in favour of more important work.
The bug is an inconvenience to users, but it does not prevent them from completing their tasks. The feature is a convenience to users.

Synonyms: optional, last, may do

The engineer may assign the work to himself while working on a high priority work because the high work provides an opportunity to complete the low priority work at less cost. If the low work in any way jeopardises the high priority work, the low work is unassigned. The engineer is thus certain that the work can be fixed quickly and without difficulty. A corollary to this rule is that low work that is assigned to a engineer must be “in progress” or “fixed” states.

The Problem with “Medium”

It might be argued that when the engineer has an opportunity to fix a low or a medium bug, he must choose the medium one. This rules does not define a practical distinction between medium and low. There is no commitment to fix the medium bug; it will not be scheduled for fixing. A engineer chooses to undertake a low bug because he sees an opportunity to fix it while working in the affected code. The engineer is choosing to do unscheduled work because he is certain it does not jeopardise his scheduled work. The engineer might see an opportunity to fix a medium and a low bug at the same time, but that is unlikely.

It can also be argued that ‘critical’ is ‘high’ and that ‘high’ is ‘medium’. True, that is a matter of semantics. The crux of the issue is that there are three practical classifications of work. The words chosen to describe the classifications could use the tofu scale of hard, firm, and soft. People who are unfamiliar with triage will appreciate names that convey the kind of attention the issue will receive.

Some teams with a large number of bugs prefer to keep a pool of medium work from which releases are planned. Items in the pool may be escalated to high if it is perceived that once work is started, there should be a commitment to complete it as scheduled. This work is different from low work because the work makes a substantial improvement to the application, but like low, there is no commitment when the work will be completed. It can be argued that work starts on medium bugs and features because of changes to other priorities, certainties, or the number of users it affects.

Consequences of Misprioritised Work

Stakeholders often use reports that list the prioritised work for a release and for each engineer. When work is misclassified there are two commonly observed consequences: a decreased in certainty, and a decrease in communication.

In the first consequence, the engineer’s effort may be wasted; there are issues that have more need and certainty. Engineers, and other stakeholders, are often tempted to complete the misdirected work after the misclassification is discovered because it is assumed that it is better to always deliver something finished than nothing at all. This is a risky choice, because it jeopardises work in future releases. By working on less important work, the engineer is decreasing the certainty of the more important work.

The second consequence is that the engineer ignores the list and he works on issues according to some other source, such as the opinion of another stakeholder. While the engineer is working on the correct issue, it is unclear to other parties what work is going on and when will it be completed. Users may abandon the project in frustration. Planners cannot coordinate all the stakeholders.

The first consequence is possibly a failure to do re-prioritisation during the triage process, but second consequence is a total failure in the triage process. Why would anyone do triage if the prioritisation will be ignored? How can work be coordinated if the work is unknown to all stakeholders? Why would users trust a project if it does not do what it says it will do?

Work must be reprioritised during the triage process to ensure that engineers are working on the issues with the most need and certainty. Engineers must work from the list or prioritised issues.

Indicators of Misprioritised Work

The rules of practical classification provide tests for misprioritised bugs, features, or tasks.

  • The work is critical, but it is not assigned and targeted for release.
  • The work prioritised as high, but it is not assigned and for a release.
  • The work is high, but have not been worked on in 3 releases.
  • The work is low and unassigned, yet it is targeted for a release.
  • The work is low and assigned, but the engineer is not working on it.
  • The work is considered to be triaged, but it’s priority is not critical, high, or low.
  • An engineer is assigned more work than he can accomplish in 3 releases, and it cannot be reassigned.

Launchpad font-size broken by design

I looked at Launchpad bug #523189 today. This bug cannot be fixed until Launchpad abandoned YUI-Font rules — percentages have unpredictable results when pages are constructed from fragment. Canonical own Web guidelines specify the use of pixels.

Launchpad uses YUI-Font to normaize font sizes across browser and OSes. It stipulates that all font sizes must be expressed in specific precentages to get the expected point size. This is difficult to use because browsers know that percentages are relative; nesting classes have surprising results.

The following text uses nesting with the same percentages that Launchpad uses.

An example of broken font-sizes in Launchpad

An example of broken font-sizes in Launchpad

Launchpd pages are constructed from many html fragments. The fragments are intended to be usable in many places on a page and display the the same way. Launchpad cannot use percentages for font-size.

Encouraging contribution on the project page

I met with Vish at UDS-N to discuss encouraging contributions to the One Hundred Paper Cuts project. The issues he raised demonstrate that the page design is not meeting the requirements we set in the Launchpad 3.0 UI designs. You will see a common layout in Launchpad pages where a wide narrative block is above two blocks.

Who, what, where, when, and hows of a project

The narrative blocks on a project page (and any Launchpad page using the same layout) must explain what the you are seeing and why it exists. This information is entirely dependant on the project owner.  One Hundred Paper Cuts does this very well. I can read that the project chooses 100 small bugs that can be fixed to improve the common Ubuntu user experience. The project summary says everything in one sentence. The projects description elaborates and explains the value.

The left block below the narrative provides information about who works with the project, and where is the code for the project. Some projects have information about the organisation that the project belongs too. In the case of One Hundred Paper Cuts, the information about “where” is missing and there is no way for Vish to provide it. This project does not have code, it organises work to fix the code in other projects. This is a legitimate use case. Launchpad does not require projects to have source code, but it does not let project owners state what it does as an alternative. I do not know how to solve this.

I would like to tell contributors that this project is affiliated with Ubuntu and User Experience, but Launchpad does not have a concept of project affiliation or tags. I would like to see similar projects that I could contribute to. There are no plans to provide this feature, but we are discussing what needs to be done to fix project groups which has overlapping issues. We may have an opportunity to build this feature next year.

The right block under the narrative is intended to be a call to action. Every page that uses this layout should using this block to encourage users to contribute. For distro series, this block shows the packages that need upstream information. For projects, this should summarise the planned work and what needs to be done. I see a fragment of the series and milestone time line, but it does not tell me what is being done.  The milestones names are not informative. The name implies that the milestones are a sequence, but the 10 milestones are worked concurrently. One Hundred Paper Cuts uses feature-directed milestones. Launchpad supports this work pattern, but the time line does not describe it. Vish could rename the milestone to reveal the theme of the feature, eg rename maverick-round-10-sc-metadata to software-centre-metadata.

Fixing the name is easy, but the information about the work will still not appear on this page. The project index page used to show a summary of the active milestones. I have pondered adding the current milestone to the page so that contributors can see what they can do right now…but how do I show 10 concurrent milestones? Pages that work with milestones are prone to timeouts. I cannot consider restoring milestone information until we solve the long python computation times needs to summarise them.

We can fix some of issues that the project index page has in the next few months, but I think some larger feature and design work is needed to really make the page work for all projects.

Launchpad Answers at UDS-n

While attending UDS-n, I was invited to two separate and contradictory conversations about Launchpad Answers.

Jorge Castro is considering Ask Ubuntu as the official Ubuntu service for managing user questions. It is a nice service. The question refining and member reputation features are compelling. I think there are two changes that need to happen to make this happen:

  1. Launchpad should let project register an external support service. I already have plans do this this later this month. Projects will be able to specify the URL of a site or email address of a list where support can be found. The external service can be used with Launchpad Answers, or by itself. This will permit communities to register the service they are already using, or allow end-users to choose the service that meets their needs.
  2. The Get help online page accessed by Ubuntu desktop applications must be updated to point users to the service the Ubuntu community chooses.

David Planella lead a discussion about internationalising Launchpad Answers. This is a feature we have long wanted to do, but it has never been a priority. This certainly can be done with the community’s help. While examining how users discover Launchpad Answers, we saw that the Get help online page accessed from Ubuntu desktop applications is a complete failure for non-English speaking users. The general steps to fix the non-English-speaker’s experience are:

  1. Automate POT extraction for code and templates.
  2. Add support to localise pages based on your preferred language or browser languages.
  3. Mark the translatable messages in the page templates, and this may require restructuring the information.
  4. Replace the ugly plural hacks in the view code–Zope markup does not support plurals.
  5. Enable translations for the Launchpad project.

Both David’s and George’s intentions are contradictory. The Ubuntu community needs to make a final decision regarding the future of community support before we can proceed. Stack Exchange does not support localisation either, and they do not have plans to support it.  We often talk about replace karma, no one will argue a case to support it, but replacing it is not a priority. Launchpad has an incomplete feature called standing that is like reputation; I am consider removing it because I do not like to maintain unused code.

Concluding the bridging the gap theme

Many people have noticed application pages are changing on Launchpad. The pages might state that Launchpad does not know where a service is hosted, or the layout looks more like the common Launchpad design. These changes are a part of the final feature the Launchpad Registry team is contributing to the bridging the gap theme: To clearly state what Launchpad knows about were a project hosts a service.

This simple statement is a very large change to how Launchpad collects and presents information about the applications used by a project. The underlying goal is one that anyone who has ever tried to contribute to a project will sympathise with–“I want to contribute and I need to find where the project is hosted”. Launchpad aggregates project information and it hosts projects. Many projects use one or two Launchpad services like bug tracking and code hosting, but manage support or specifications elsewhere. Each service needs to tell users where or how they can accomplish their task. This also means that when Launchpad does not know, it should say so and not imply the project uses Launchpad.

This feature is also an opportunity to reconcile the differences between how applications present the same information. Once this opportunity was agreed to be in scope, I proposed the common experience for the five Launchpad applications (Answers, Blueprints, Bugs, Code, and Translations). The front pages will state whether the service is unknown (tell us), hosted externally (and tell you where), uses Launchpad (use it now), or not applicable. The pages will also explain if information may also be tracked in Ubuntu. The pages will not be indexed by search engines when the service is unknown. The layouts of the pages will be the same so that your experience using one application is applicable to all applications.

At first glance, this appears to be a feature that a team could deliver in a month, but that is not true. This is a very large change. We changed how launchpad collects information and the change had to be compatible with the current information so that the UI changes could be made without preventing you from using Launchpad. The description of 4 states for 5 apps is a gross simplification. When I say project, I mean a valid target for the applications, which could be a project, project series, project group, distribution, distro series, distro package, user, or team. This is 4 x 5 x 8 pages/conditions. The number of interaction we are building is much less than 160 pages because not all states apply to every app, nor does every kind of thing I listed. The Registry team is designing, building, and verifying 80 distinct pages. This is a lot of work for a 4 person team (this too is an exaggeration as most of my time is spent fixing oopses and planning new features). We appreciate your patience and we welcome your bug reports.

Remixing Ubuntu using Launchpad

Creating an Ubuntu remix is a big effort that requires the orchestration of a lot of small pieces. Many users assume they want to create a project or distribution to manage this, but neither can manage all the pieces. I recommend using a Project Group to manage the unique parts of the remix, and a team with a Personal Package Archive (PPA) to define the unique and common parts that are published.

Let me state first that while this scenario does describe what many call a derivative distribution, Launchpad does not provide all the features you want in a distribution. Ubuntu is the only distribution that has packages built by Launchpad. While you could have a distro whose series parent is an Ubuntu series, your distro will have no source packages, binary packages, or mirrors. The archive management tools are exclusive to Ubuntu. Translations are also exclusive to Ubuntu. This is not out of selfishness, it is just a matter of fact that these seminal services were built for Ubuntu, and extending them to support other cases is a lot of work.

You can use other Launchpad features to accomplish a remix. This practice was discovered through trial and error by users. It also reveals that in most cases, users really do not want a Launchpad distribution, because they have original work that that stands on its own.

Launchpad Project Groups are a way for a community (a team) to control several projects. The Project Groups drivers are automatically project drivers, allowing a team to plan releases across several project are once. Project Groups allow you to see a unified view the series and milestones on the sub projects.

Your projects represent the original work that makes your remix special. The original work for a project is the code, artwork, and documentation kept in the series branches. The team that owns the Project Group should also be the owner of all the Projects [1].

Most remixes need one or more projects that provide new art for boot, login, and desktop themes. Some remixes want to provide packages for projects that are not in Ubuntu yet, so they maintain a mirror of the code in a Launchpad project [2]. Some teams are using Launchpad to host their projects–it is pretty common for a team to build specialised tools then decide to distribute them using a live Ubuntu ISO as a base.

Many teams choose to create a project to represent the meta-package that controls the default mix of packages. This is an ugly hack, and the explanation deserved more than a footnote. Since the meta-package project does not produce something that a user or system runs, it does not deserve to be a project. Launchpad projects permit communities to share code, translations, etc–these projects do not have much to share. The branch that holds the code (/debian directory) of the meta package could easily be in a personal branch [3], but that prevents the team from sharing it between themselves. A project is the better choice in this situation.

Here is an illustration of the common way to set up a Project Group that distributes its packages

ProjectGroup -- owner Team -- PPA
+ Project1 (original artwork)
+ Project2 (no Ubuntu package)
+ Project3 (team is the upstream maintainer)
+ Project4 (meta-package hack)*

The team needs an archive to distribution its original packages and updated Ubuntu packages. Any team can create a PPA from their profile page on Launchpad. Team can dput their packages to their archive and Launchpad will build them. Users can add the PPA to their sources list, install the meta-package, and get all the packages in the remix in a single install.

Many teams want to create custom versions of Ubuntu packages. The simplest way to change a package is to get the source, add a patch, then dput it to Launchpad, but you then need way to manage that patch. An alternate way to so this is to use a source package branch. Every Ubuntu package has a branch that contains the source code, debian packaging rules, and patches to build the packages. You can usr bazaar to pull a copy of a branch, make your changes, then push them to your team’s location. Launchpad beta users are testing a new feature called recipes. They allow you to describe how to merge and nest several branches to create your source package and dput it to Launchpad.

This kind of problem also explains why users and teams own archives, not projects. The archive contains packages derived from the Project Group, from other Projects that are not packaged in Ubuntu yet, and modified packages from Ubuntu. The team’s archive is a single source that provides a diverse set or packages. The team is not the owner of the projects it packages, and it does not need to be to distribute them. Other users and teams can reuse your branches to make their own remixes. Your change may make their way into Ubuntu.

[1] Any user can make a project be a part of the Project Group you control. This is a bug. Control and affiliation are conflated in Launchpad and this needs to be fixed.

[2] You may not want to make mirrored projects a part of your group because you would be happier if someone else managed it. You can always make someone else the maintainer if a volunteer appears.

[3] Since projects are shared. there is no such thing as a personal project. You do not need a project store your personal branches. All Launchpad users have a location to keep non-project branches, but I have never seen a Launchpad page tell me about them :( Also “+junk” implies the branch has no value, which is wrong…it is versioned and public, of course it has value, it is just not a source for a project :( See https://help.launchpad.net/NonProjectBranches