Writing in the OpenCraft Blog#

Members of the OpenCraft team publish blog posts on our website. Such blog posts provide news about OpenCraft, updates about the Open edX platform, technical tutorials, and other news. If you have an idea and would like to prepare and publish a blog post, you are welcome to!

Who at OpenCraft is responsible for maintaining the blog?#

The Marketing Specialist (currently Gabriel D'Amours) is responsible for maintaining the blog. He publishes blog posts as per a specific schedule.

Contact him if you have any questions!

Blog Publishing Process#

The following is the procedure to publish an article on the OpenCraft Blog.

Share your idea#

Have an idea for a blog post? Create a public thread on the OpenCraft Discussion Forum, draft a small brief for your blog post, and ping the Marketing Specialist. There is no formal approval process, but team members might request that you refine your idea.

Create a ticket#

Once ready:

  • Create a ticket to prepare the blog post. The epic should be OC-5152, and the Account should be Marketing.
  • Find a reviewer
  • Assign the Marketing Specialist as 2nd reviewer

The budget for the ticket should be 10h. The budget is distributed as follows:

  • 6h for preparing the blog post (assignee)
  • 3h for the review process and proofreading (reviewers)
  • 1h for publishing (Marketing Specialist)
Write a draft#

Write a draft in a Google Doc. Make sure the doc is in the following folder, and set permissions so that any member of OpenCraft can edit the doc.

Once ready for review, ping your reviewers.

Proofreading Process#

Once the draft has been reviewed and the comments addressed, it's time to have your copy proofead. Follow the steps from proofreading procedure in the Handbook to have your copy proofread.


It's now time to create the blog post in Wordpress.

  • Log into (if you don't have an account, ask the Marketing Specialist to create one for you)
  • Go to Posts -> Add New
  • Add a title
  • Start the post with This article was written by team member [name] (github link) -> example
  • Paste your copy. Headings will be used to generate a table of contents -> example
  • In the right-hand vertical menu:
    • Pick a Category
    • Add relevant Tags
    • Set a Featured Image. This image will be used as the cover image for your article. Make sure you have permission to use the image (Unsplash) is great for this)
    • Attribute credits for the image at the end of your post
  • Save draft and ping the Marketing Specialist on your Jira ticket when ready.

Do not publish the post! The Marketing Specialist will do it, as per the schedule.

Our blogging platform in Wordpress uses a Search Engine Optimization (SEO) tool called Yoast to review your copy and suggest changes that will increase the searchability and placement of your article on search engines.

Once your copy is in Wordpress, the Yoast tool will automatically review the copy and suggest SEO improvements. The suggestions can be found in the post creation tool, in the right-hand vertical menu, under "SEO Analysis".

We encourage you to take the suggestions into accounts, and do the necessary changes to your text to improve SEO readability. You can ping your reviewers for one last quick review after this, if necessary.

Client Onboarding And Offboarding#

This section describes the processes we use when we welcome new clients and say goodbye to existing ones.

Creating a work epic#

When working with a new lead or client, a Jira epic can be created to: * Capture information that is essential or useful to developers * Group tasks together and facilitate coordination when multiple discussions/discoveries are involved * Find a client owner early in the process

The moment at which we create a work epic for a new lead or client changes from project to project.

If no discovery is required, the epic can be created after contract signature.

If an initial discovery (blueprint) process is required, epic creation can be handled in one of two ways: * If doing a single and overall straightforward discovery, there is probably no need to create an epic until the contract is signed. * If the discovery process involves lots of discussions, multiple discovery tasks, and multiple meetings, then we should create and assign an epic during the blueprint/discovery phase.

Once a client has accepted our estimates#

If the proposal resulting from the discovery is accepted, we move its epic to the "Accepted" column in Jira, and set a time budget and a timeline based on estimates from the discovery. Discoveries and epics are related through their estimates: tasks in an epic use the estimates and budget of the features the client selected from the quote, which was based on the discovery document. You can validate this with the Business Development Specialist.

New client onboarding#

Here's the workflow we use when a new client accepts our quote:

Client Onboarding workflow

Offboarding process for departing clients#

We use the following steps to complete the offboarding of an existing client:

Client Offboarding workflow

During the offboarding process, the following technical document provides guidelines on how to handle client data.

OpenCraft Coding Standards and Best Practices#

Here are the guidelines that OpenCraft follows with all of our software development. Some of these are not strict rules, but all of them are the standards that we aim for.

Open Source#

We are an open source company which means that all software we create should be open source by default (unless there is some compelling or legal reason not to).

New software that we create should generally use the AGPL or GPL license.

Documentation or other non-software works that we create should be licensed under a Creative Commons license, usually CC BY-SA 3.0.

In addition, any time we make a change (feature, bugfix, etc.) to an external software project (like Open edX, Django, etc.), we contribute that change back to the project. (Sometimes they won't accept it as a contribution, but we always try.)

Coding Standards and Best Practices#

1. Do your best to ensure you've written clean, maintainable code.

  • Remember "Don't make me think!": use descriptive variable/function/class names in your code and comments to make your code as easy to read as a book.
  • Short, simple code is usually better than long, complex code, but don't fall for the temptation of writing code that's visually dense, which is hard to read and understand. Add docstrings, blank lines, and comments to space things out and make your code more readable.

Here is an example, showing the same python function written in a "bad" and "good" way:

########## Bad Example:

def get_anon_id(user):
    if not user or not user.is_anonymous:
        raise TypeError("user is not anonymous")
    if hasattr(user, '_anon_id'):
        return user._anon_id
    cr = crum.get_current_request()
    if cr and cr.session:
        if "_anon_id" not in cr.session:
            new_id = "anon{}".format(uuid4().hex[:20])
            cr.session["_anon_id"] = new_id
        return cr.session["_anon_id"]
        raise RuntimeError("No current request!")

# ^^ This code looks simple but is full of subtle actions that aren't well explained.
# It will take someone quite a while to figure out what the code is actually doing
# in various cases, and even longer to refactor.
# Let's fix it:

########## Good Example:

def get_xblock_id_for_anonymous_user(user):
    Get a unique string that identifies the current anonymous (not logged in)
    user. (This is different than the "anonymous user ID", which is an
    anonymized identifier for a logged in user.)
    Note that this ID is a string, not an int. It is guaranteed to be in a
    unique namespace that won't collide with "normal" user IDs, even when
    they are converted to a string.
    if not user or not user.is_anonymous:
        raise TypeError("get_xblock_id_for_anonymous_user() is only for anonymous (not logged in) users.")

    if hasattr(user, 'xblock_id_for_anonymous_user'):
        # If code elsewhere (like the xblock_handler API endpoint) has stored
        # the ID on the AnonymousUser object, just return that - it supersedes
        # everything else. (See the xblock_handler API endpoint for details.)
        return user.xblock_id_for_anonymous_user

    # We use the session to track (and create if needed) a unique ID for this anonymous user:
    current_request = crum.get_current_request()
    if current_request and current_request.session:
        # If we already have a random ID for this anonymous user cached in the session, return it:
        cache_key = "xblock_id_for_anonymous_user"
        if cache_key not in current_request.session:
            # If not, generate a new random ID and cache it in the session:
            new_id = "anon{}".format(uuid4().hex[:20])
            current_request.session[cache_key] = new_id
        return current_request.session[cache_key]
        raise RuntimeError("Cannot get a user ID for an anonymous user outside of an HTTP request context.")

2. Document your decisions

  • When you're building something new, you'll make a lot of decisions about how it works. Write those decisions down so that other developers can understand more easily.
  • It's tempting (and helpful) to put these details into a pull request description, but pull requests are temporary and hard to find once merged. It's much better to put the details of your decisions into the codebase itself as a docstring (for small components), a README, or an Architecture Decision Record (ADR) (example).

3. Write tests for your code

  • Testing is critical for designing robust, high quality software components and avoiding regressions.
  • "Unit Tests: Best and Worst Practices" provides good tips about the role of tests and how to maximize their value. ("It's overwhelmingly easy to write bad unit tests that add very little value to a project while inflating the cost of code changes astronomically.")

4. Backend guidelines:

  • Choosing a language: we default to using Python for most new projects for simplicity and consistency.
  • Follow the edX Python Style Guide (even for non-edX projects, unless the project has its own style guide).
  • Use pycodestyle and pylint to enforce coding standards automatically

5. Frontend guidelines:

  • Follow the edX JavaScript Style Guide for JavaScript in edX projects.
  • Use TypeScript for non-edX projects.
  • Ensure that any UI you build follows best practices for accessibility and complies with the WCAG 2.0 Level AA standards:
    • Every UI component and content item has a text version (alt text, screenreader text), so that non-visual users can still understand and use it.
    • The UI can be used with a keyboard only (tab order, keyboard controls).
    • Text colors have sufficient contrast.
    • See the complete checklist/cheatsheet (levels A and AA only).

More in-depth guidelines and discussion of particular technologies can be found in our technical documentation handbook.

Infrastructure as Code#

As much as possible, infrastructure, server provisioning, and devstack setup should be defined by code and version controlled using git.

In particular, this means:

  • AWS and OpenStack/OVH infrastructure should be configured using Terraform.
  • Set up for the environment your application requires (installing apt packages, etc.) should be scripted using either Ansible or a Dockerfile.
  • Setting up client-specific devstacks should be automated using bash scripts or whatever else is convenient.

Contributing Features to edx-platform#

For feature contributions to the Open edX core platform in particular:

Discuss with the team and/or edX to determine if the feature you're building should be part of the core platform or should be a plugin (like an XBlock or a django app plugin). Generally, if it provides a platform feature that most of the community will use or provides a foundation for building other functionality, it would be a good candidate for the core platform, and if it's a feature that only a minority of Open edX instances are likely to use, it would be better as a plugin.

If you are writing the feature as a plugin, ensure that it only uses stable public APIs such as the XBlock API, the Django App Plugin API, and/or any inter-app API ( files within each Django app in the core platform). If there is no public API defined for the integration you need, modify the core platform to provide the API that you need, e.g. in an file, and contribute the API to the core platform.


We at OpenCraft lean heavily on asynchronous processes, and write tons of documents as a result. Any team member at OpenCraft has access to a proofreading service for work-related documents. We encourage you to use this service as needed, to improve the quality of your documents (discoveries, documentation, blog posts, etc.)

We work with a proofready company which employs humans to proofread your text and make suggestions. Here is how to submit your copy for proofreading:

  • Upload a Google Doc containing your copy to the "To Proofread" folder
  • Send an email to with a link to your document, asking them to proofread the document.
  • A proofreading professional will review your copy and submit a commented version in the "Proofreading done" folder. They will ping you once done.


Pull Request#

For every task that results in new/changed code, you will create one or more pull requests ("PR", also called "merge requests" or "MR" on GitLab). Each pull request will always go through an internal review by another OpenCraft developer, and will usually go through an upstream review process as well.

When to open a pull request#

In general, all code changes to a git repository should happen through a pull request.

What about tiny, safe changes (like fixing a typo, or changing a minor deployment setting in a configuration repository)? Yes, even then: open a pull request, don't just commit to master. In this case, you don't need to wait for a review (you can merge it right away), but it's important to still use a pull request.

Open PRs early! Your code does not have to be complete before you open a PR. It's usually a good idea to open the PR early and push your commits regularly - not only does this keep a backup of your work, but it helps your reviewer give early feedback and get a sense of how complex the code review will be.

Why to open a pull request#

Pull requests are important for facilitating the code review process, but they do more than that:

  • Pull requests send an email notification to anyone "watching" the repository, so they can stay informed about new developments.
  • Pull requests will usually trigger an automated build, to ensure tests are passing, provision a test environment, or even to deploy the changes when you merge them.
  • Pull requests provide a way to associate the changes with a particular JIRA ticket (this can also be done via the git commit message, but a PR title/description can be edited by anyone with admin access to the repo, and a git commit message cannot.)
  • Pull requests provide a public place to give context for the changes, as opposed to JIRA tickets which are often private.

What to include in a pull request#

When writing a pull request, you want to make it as easy as possible for everyone involved to understand the changes you're making, to review the code, and to test your changes before merging. Here are things you should include to achieve that:

Title: Give the pull request a descriptive title, and include any OpenCraft JIRA ticket IDs in square brackets as part of the title (note that you can edit the title later if needed); it's really important for OpenCraft's workflows that we can find pull requests from JIRA tickets and vice versa. We generally do not include ticket numbers from a client's private JIRA in the pull requests, although the "Yonkers" client requires that their JIRA ticket numbers be put in the branch name. We also generally don't mention the client's name unless they have asked us to credit them.

Example title: "[SE-1234] Implement UI to import a content library from a .tar.gz file"

Decisions: Remember that pull requests are not often seen after they merge - so as explained in Coding Standards you should always document major design decisions within the codebase itself (docstrings, README, ADRs) and just link to that explanation from the PR description.

Template: The edx-platform pull request template shows what is expected in a good pull request description; we recommend using this template when you open a new pull request.

If you are opening an edx-platform pull request, Ocim will automatically provision a sandbox for your PR, using its branch. If you need to enable some specific settings (via ansible variables) for the sandbox, include a section like this at the end of your PR description:


Other tips on what to include:

  • You may also want to review the edX PR Cover Letter Guidelines.
  • Keep the recommendations from the edX contribution document in mind. For the individual contributor agreement, you are submitting code on behalf of OpenCraft, so that is inapplicable; you don't have to sign it.
  • Remember who you are writing the description for: other developers and product/community managers, who may not have as much context as you do about these changes. You need to explain your changes clearly and convince the reviewers that the change provides value for the codebase. (For example, if your PR to add support for SWIFT generalizes the storage backend, the latter benefits everyone, not just SWIFT users -- focusing your PR title and description on it will be more appealing to reviewers who don't use SWIFT.)

edX Pull Request Types#

If you're performing a pull request against an edX repository, you must keep in mind what type of pull request you're making. edX is sometimes our client and other times a community partner. The process for interacting with them differs slightly depending on the roles we are playing at that particular time.


OSPR, or 'Open Source Pull Requests', are pull requests that result from our work either with other clients or as independent contributors to the Open edX platform. OSPRs tend to be reviewed slower than blended tickets since they are unlikely to be immediately relevant to edX's use cases. They may cover fixes for bugs edX has not run into or features that one of our clients have requested and we're seeking to upstream to avoid code drift.

When creating a pull request against an edX repository, by default, an OSPR ticket will be created by edX's bot, edx-webook. This ticket is created in the Open edX Jira for prioritization by the Open edX team.


BD, or 'Blended' pull requests are pull requests that result from work performed for edX as a client. These requests should be reviewed on high priority because edX is relying on the changes in these pull requests. See the main article on working with edX for more information.

How to create meaningful commits#

Since OEP-0051 is merged, edX adopted Conventional Commits as part of the Change Transparency initiative.

For more information about how to create proper commit messages, please refer to the latest OEP-0051.

Additionally, you can read more in this article about why it matters to have meaningful commit messages.

How to open a pull request#

  1. ✏️ Commit your changes on a branch, and push the new branch to the open-craft fork of that repository.
    • e.g. For changes to edx-platform, you should generally create your branch based on the upstream edx/edx-platform master branch (do not use the open-craft/master branch, which is very old), and push your new branch to the open-craft/edx-platform fork.
    • If the repository you are modifying isn't an OpenCraft repository and hasn't been forked to the open-craft organization on GitHub/GitLab, you'll need to do that first. If it's a GitHub repo, after you fork it, only you will have write access by default - so go to "Settings" > "Manage Access", and add the "Core" team as "Admin" and then grant "Write" access to both "New Members & Candidates" and "Short Term".
    • Exception: certain clients whose repositories are private (closed source) do not want their repositories forked. If a repository is private and no open-craft fork exists, ask the client owner to find out where the new branch should be pushed.
  2. 💬 Open the pull request using the GitHub or GitLab UI (or app or cli tool). Use the title and template from "What to include in a pull request", above.
  3. 🔗 Link your PR to the OpenCraft JIRA ticket: From the ticket in JIRA, click "More" > "Link" > "Web Link" and paste the URL of the pull request. Put a description like "Upstream PR".

👩‍💻 Finish coding: If you've opened the pull request early (as recommended), then at this point, keep developing it until it's complete and ready for review. You can also ask your reviewer(s) to do a quick review of the work in progress if you'd like (but don't necessarily wait on that to do further work, as your reviewer may not have time to help on short notice).

  1. 👀 Self-review the PR: take a minute to "reset" yourself, then read through the entire PR description and code diff as though you're a reviewer seeing it for the first time. You'll probably find a few typos and things that aren't clearly explained - fix those now. If you haven't already, work through your step-by-step manual testing instructions now to confirm that the instructions are clear and the code is working.
  2. 🚩 Check for migrations: If the PR has introduced new migrations, you and your reviewers need to take special care and possibly split the changes up into two or three separate pull requests. See "Everything About Database Migrations" for details.
  3. Wait for the CI builds to complete, and address any test failures. Your reviewers should not have to point out failed builds. Check if the build passed, but also check test coverage reports generated during the build, if available.
  4. 🔗 Link to the sandbox, if available. A sandbox makes it easier for reviewers to test your code. For edx-platform pull requests, Ocim will try to create a sandbox for you automatically, but you'll still need to check that it worked and link it to the PR. For other PRs, you'll need to create a sandbox manually if possible. See "Sandbox process details" below. At this point, the sandbox may also be out of date, so make sure it's running the latest version of your code.
  5. 📡 Ping your OpenCraft reviewer on the JIRA ticket that this is ready for review. If there are multiple PRs, include a link to the PR in your ping. (It's not necessary to also ping them on the pull request itself.)
  6. 💯 Address the feedback from your reviewer, and get their approval.
  7. 📡 Ping your upstream reviewer (all PRs to external repositories) or core committer reviewer (only PRs to edX repositories), if you know who they are. If this is an open source contribution / OSPR, you may need to wait for edx / the upstream project to assign a reviewer. If this is an OpenCraft repository/project, skip this step and the next.
    • Just as for internal reviews, the Core Committer needs the be assigned before the sprint starts to avoid injections in the Core Committer's sprint
  8. 💯 Address the feedback from your upstream reviewer, and get their approval.
  9. Squash your PR down to "one commit per major change", with a clear commit message. Put useful context from the PR as additional lines in the commit message if useful. You should also rebase on top of the latest master branch while you do this, and fix any merge conflicts that may arise.
  10. Wait for the CI builds to complete with your squashed changes.
  11. 🚀 Merge the PR (if you have permission) or wait for one of your reviewers to merge it.
  12. 🔭 Monitor the deployment:
    • For PRs to edX repositories, it will likely get deployed by CI within hours of your PR merging. Once your PR is merged, you'll get a PR comment on GitHub when it has been deployed to the edX stage server. When you see that, you should verify it on the stage server to make sure it's working as expected.
    • For other repositories, deployment processes vary. In any case, make sure it works once your PR gets to stage and prod, and try to be available in case there are any issues.
  13. 🗑️ Delete the branch after the PR has merged (use the delete button GitHub adds to the end of the PR). Otherwise, repos get too cluttered with old branches.
  14. ⏭️ At this point, you may need to backport the PR to another branch/fork, depending on what client it's for. If not, you're done! Mark the JIRA ticket as Merged. Then let the client know (if applicable) and mark the JIRA ticket as "Delivered to client."

How to request Core Committer review#

Note: This section is about edX related repositories. If you are looking for the Core Committers of OpenCraft, please look for the people next to "OpenCraft" in this table.

Getting a Core Committer review has its own workflow in Jira. The workflow is applicable for those tickets which will require upstreaming. When you need a Core Committer to review your changes, the process adjusted as the following:

  1. When you take a ticket, find/ask a Core Committer to do the review, and they can assign themselves using the dedicated "Core Committer" field
    • When you get a Core Committer review, you may skip the usual code review ("Reviewer 1") at your decision.
    • In case a Core Committer is not available or you need help communicating with edX, to ensure that the Pull Request gets the desired priority and attention from edX ping the OSPR liaison for your cell.
  2. Implement the required changes.
  3. Open a upstream Pull Request.
  4. Ask an optional - but recommended - code review from "Reviewer 1".
  5. After review feedbacks are addressed, ask a Core Committer review.
  6. When the changes are approved, merge the PR.

In some cases, edX will do a product review if needed. While waiting for input from edX product, still move the ticket to “External Review/Blocker”.

Sandbox process details#

If you open a PR against edx-platform, Ocim will automatically provision a sandbox for that PR. Once the sandbox has been provisioned (it takes about an hour), update the PR description to include links to the sandbox.

If you open a PR against a different repository:

  1. Manually create a sandbox in Ocim. Include the ID of the JIRA ticket ("OC-1234", "BIZ-5678", etc.) in the name of the sandbox.
  2. Link the instance to a PR from Ocim's Django admin (you may want to create a new watched pull request without linking the sandbox to it first, and use the Django shell to locate and link the sandbox to the watched pull request in a second step - this might be easier than locating the instance in the Django admin UI for creating/editing watched pull requests). Ocim will regularly check the PR's status and automatically archive the sandbox as soon as the PR is closed. If you didn't link the instance to a PR, you need to make sure to archive all sandboxes before moving a JIRA ticket to "Merged" (e.g. put it in a checklist item on the ticket to help you remember).
  3. Update the PR description to include links to the sandbox.


The current document describes the stages of recruitment and the various evaluation points that occur during the process.

Launch of a recruitment round#

  • The epic planning managers are responsible for determining when the availability needs of their cells will require to launch a recruitment round. They communicate this need as much as possible in advance to the recruitment managers and the CEO - ideally at least 1 month before the availability is required, to provide enough time to complete the round.
  • A cell should always target having some extra availability, to allow to accept new projects without requiring too much last-minute recruitment, which is more stressful for the cell and the recruitment managers. On top of the required availability, plan for 1-2+ extra newcomers for availability margin, plus planning ahead to replace any newcomer that doesn't pass their trial.
  • The CEO publishes the job ad, which direct candidates to submit the recruitment form.
  • The CEO informs all recruitment managers of the upcoming start of a recruitment round, and creates a workflow board to track the progression of the round's process.
  • The recruitment managers who participate to the recruitment round include a ticket in their upcoming sprint for it, and note on the comments of the workflow board how many newcomers they are looking for.
  • The candidatures are available to the recruitment managers immediately upon submission, without filtering. Each sprint manager assigns 1/X of the unassigned candidatures to themselves (the oldest submissions, with X being the total number of cells currently recruiting), splitting the reviews between the other recruitment managers who are actively recruiting. ** To allow cells with higher recruitment needs to process more candidatures more often, and encourage faster candidatures reviews, this self-assignment operation can be repeated up to every two days by each recruitment manager

Pre-selection of candidates for interviews#

Recruitment managers do a pre-selection of candidatures, to invite for an interview. It is a very basic filter over the candidatures - we don't want to be too selective at this stage, as it can still be quite hard to tell whether a candidate would be a good fit just from that information. So there are few criterias, but they are strict - if a candidate fails to pass any of these, they are eliminated:

Contribution to third party projects#

We want to see at least one contribution (PR/patch) to a third party project, which isn't completely trivial (a small bug fix is fine, but just fixing a typo, spacing or a missing import isn't enough, you want to be able to have something to evaluate), and which has been merged by the third party project.

No exceptions on this, it's a hard rule. This is the main filter of the pre-selection. So we check this first, and generally someone saying explicitly that they don't have contributions is enough to rule them out -- in these cases we save time by not having to look at the rest of the candidature.


  • The type of work/tech from the contributions don't need to be related to our work.
  • The recipient project can be small, but should be something that has users (see its number of stars & forks - there should be at least 10-20 of each).
  • PRs done as part of an employment are ok (that's also what we do!), but it should really be done openly, and still preferably to a third party. If the PRs are all silently merged, it means there was either no review, or it happened privately, and this doesn't really qualify as an open source contribution
  • There should also be at least a PR description, and some comments/discussions with upstream - we are looking for people who communicate.
  • We are trying to filter for people who care about contributing to someone else's project, so merely releasing code on their github, or even contributions to a project they are a maintainer of, doesn't count.
  • Since often candidates just point at their github account, we get all their third-party PRs by visiting this URL (we check this for both the github & gitlab accounts when they are provided):
  • Github:
  • Gitlab:

Proper writing skills#

Candidates don't need to have flawless spelling & grammar, but it needs to be reasonable. We think about whether the type of writting would work with a client for example. We aren't too harsh though - it can be hard to tell at times, and we can give the benefit of the doubt.

Python, Django & React#

We require experience in at least Python & Django, plus preferably React. Sometimes it's unclear - some candidates don't specify some of their experience... So we wouldn't necessarily eliminate a promising candidate who doesn't list one of those (and React is not mandatory either, just very appreciated), but we will take a note of any doubt on these, to ask during the interview.

Although if there is no mention or sign of any practice of Python, the candidate almost certainly has no Python experience, so we reject the candidature in these cases. Some candidates omit mentioning Django when they have only a small amount of experience with it, and it's still fine in that case after verification, but nobody fluent in a language omits mentioning it in their list of skills, especially when other languages are mentioned.


We also currently don't hire junior developers - from past experiences, the remote environment combined to the expected quality and efficiency doesn't work well with junior profiles, at least with our current organization. We might revisit this in the future, but we would need to put in place a specific process to allow them to acquire the required skills and experience.

At the moment, we require at least 2-3 years of professional experience as a hired developer. We sometimes make an exception for a prolific open source contributor who has demonstrated great technical and social skills in his contributions, and thus already shows a senior profile.

Also, we accept candidates who have been recently been employed by another Open edX provider, but we check for exclusivity clauses in their contract before proceeding with an interview (to be discussed with the CEO when someone from another provider applies).

Fields to fill#

In the spreadsheet containing the candidatures, besides the answers submitted by candidates, recruitment managers will see a few additional columns to fill:

  • Assigned to: The name of the recruitment manager assigned to review the candidature. We sometimes reassign some of them for the round of interviews, if there is a big imbalance -- which definitely happens, as a group of good candidatures often appear together in the spreadsheet :)

  • Status: The current status of the candidature (drop-down).

  • Python, Django, React: This is a reminder to write in the cell any of those skills for which the candidate isn't clearly experimented And then, during the interview, we ask the candidate about it. Sample value: "Django? React?" => which would be completed with the answer during the interview. For candidates which have all three pre-requirements, we put "OK" in this column - this helps ensuring that we remembered to check (or to ask).

  • Comments: Meant to contain the explanation for the recruitment manager's decision.

  • The other fields are for the interview itself - see below.

Scheduling interviews#

Emailing selected candidates#

The recruitment manager assigned to the candidature sends an email to the candidates they have selected. We use a standard email template for the content of that email. Make sure to CC the recruitment@ mailing-list in your exchanges with candidates, to allow others to follow.

Scheduling through Calendly#

We use Calendly to schedule interviews. Get an account from Xavier if you don't already have one, and setup a dedicated event for interviews:

  • Open for the week following the pre-selection
  • At times which allow a reasonable coverage of most timezones (the afternoon UTC time is usually good for that)
  • Make sure to keep the times narrow, to allow to batch the interviews - it's best for focus to not end up having them spread all over your days
  • Enable Calendar invitations, to automatically send Google Calendar invites
  • Link it to the OpenCraft Zoom account (to allow to host longer meetings), and enable the automated inclusion of a Zoom URL in the meeting invite

We need to record interviews to allow for later review by other team members. To ensure we don't forget to start the recording during the meeting, we enable the option ahead of time, in the scheduled meeting details. The setting for each individual scheduled meeting should look like this:


Recording in the cloud offer the best/most reliable way to ensure the meeting will have been recorded.

To be able to keep the candidate's reactions visible in the recording, even when they are not talking, make sure to select "Record gallery view with shared screen" in your account settings:




The interviews lasts 30 minutes, and we use a script. The script is private, to not demesurably advantage candidates who read the handbook ahead of the interview.

We don't necessarily say exactly and only the content of the script (we are not a call center ;p), but we try to stick to it, as the more similar it is across interviews, the better we are able to compare them with each other. This is especially true of the code exercise, where the way to explain it can influence significantly what the candidate will understand and how they will approach it.


During the interview, we progressively grade the candidate in the corresponding columns of the spreasheet, with a short comment on each. The rating is 1 to 5, with 5 being the highest. E.g. "5 - aced the exercise!".

Video recording upload#

We then upload the video recording of the interview to our private file drive, using the 'Gallery view' file. Also add a link in the candidate's spreadsheet entry, in the dedicated column. This will allow other team members to review it.

Final selection of newcomers#

  • The recruitment manager who interviewed the candidate takes a decision on whether to hire the candidate as a newcomer.
  • The recruitment manager assigned as a reviewer reviews the selection and interviews. A column in the spreadsheet indicates the name of the reviewer for each candidate, beside the assignee who evaluates the candidate.
  • The CEO does a second review of the interviewed candidates which both recruitment managers agreed to accept. If it looks like the candidate could be confirmed, the CEO meets the candidate for a second interview, to take a decision and to discuss contracting terms.
  • The recruitment managers send a rejection email to the candidates they have interviewed and who have been refused.

Onboarding & Trial Period Evaluation#

Once a newcomer has signed their contract, the CEO creates an onboarding checklist for them, and completes the items from the checklist assigned to him, which includes notifying the other roles involved in that process.

Once the newcomer has access to the tools and joined the team, the onboarding and trial period starts.

Since newcomers may start at any time during the sprint, this process overlays the sprint process. Newcomers are expected to participate in sprint planning meetings, commit to tasks for the upcoming sprint, and practice time management using the sprint planning tools and by updating the Remaining Time estimate fields on their tasks.

As with all things at OpenCraft, this process is continually being reviewed and improved, so please provide any suggestions or feedback on your onboarding task.

Newcomer Weeks
Week -1 Prior to your arrival, we will arrange for a core team member to be your mentor and to review your onboarding task.
We'll also arrange your accounts and access to email, JIRA and the other communication tools.
Week 0 Work on your onboarding task, which involves reading documentation, completing the onboarding course, and setting up an Open edX devstack.
You'll also have a newcomer-friendly task assigned to work on in the first week, after finishing your onboarding.
Attend the 121 meeting scheduled by the reviewer of your onboarding task to say hello and discuss your progress.
If your devstack gives you trouble, be sure to ask your reviewer or on the Mattermost #devstack channel for help, and/or arrange a synchronous meeting to work through any issues.
Week 1 You've likely finished the onboarding course and your devstack setup, and are ready to work on a newcomer-friendly or other small task.
Reach out to your mentor or the sprint firefighter to help find tasks and a reviewer from the core team to help you.
To avoid spillover, we recommend against pulling new tasks into the current sprint in the first instance -- the review cycles can often take more time than expected. So instead, especially if a new sprint is starting soon, commit to a task in the next sprint, and work ahead.
Week 2 At the end of this week, your mentor and 2 other core team members will complete a screening review of your work so far.
This review exists to provide early feedback, and to identify extreme issues like a failure to communicate within 48h of pings on tickets and Mattermost, or cases where excessive time has been logged to tasks without sufficient explanation or outcomes. In this case, we would give notice that the trial period will end. But if you're communicating on your tasks and making progress, then your trial will continue as scheduled. Your mentor will pass on any feedback -- positive and negative -- from this review.
Week 3 By the end of this week, you should have completed some tasks, with story points totalling around 8-12 points. If you haven't, bring this up as soon as possible with your mentor.
If you've had spillover, consider what went wrong during these tasks and talk about it with your mentor.
Take care not to overcommit during the next sprints to get this under control. Time management is one of the hardest parts, so after each sprint ends, take care to ensure that the Sprint Commitments spreadsheet (linked from each cell's weekly sprint meeting) is accurate, and your spillover is improving as you progress through the trial period.
Week 4 By this time, depending on when you started, you've completed 2-3 sprints, so it's time to ensure that you're completing a breadth of tasks to showcase your skills.
Have you taken on increasingly difficult tasks?
Have you submitted a PR to the Open edX platform?
Have you launched appservers or contributed to Ocim?
Have you completed any devops tasks?
Have you been the primary reviewer on some tasks?
If not, try to find tasks for the next sprints which would fill these gaps, and discuss any cell-specific expectations with your mentor.
Week 7 This week will be your developer review.
All the core team members in your cell (plus one developer from each other cell) will review your tasks, PRs, and communications, and vote on whether to accept you into the core team, extend your trial period, or end your trial.
All reviewers have to agree to confirm a new core member. We each do our own evaluation independently, and then discuss if there's a difference of opinion.
Week 8 This marks the end of your initial trial period -- Xavier will meet with you to discuss the results of the developer review.
If you're joining the core team now, congratulations! There will be a small core team onboarding task to complete in your next sprint, and you can continue logging "onboarding" time to your onboarding ticket for a while.
If your trial period has been extended, that's great too! Xavier will provide specific details on the improvements required during the extension, and it's really important to focus on these areas during your extension.
Week 11 If your trial period was extended, the core team will do another developer review, focusing on your improvements during the last 2 sprints.
Week 12 This week marks the end of your extended trial period, if applicable. Xavier will let you know the results of the second developer review.

Evaluation criteria#

The screening and developer reviews will be evaluated on the following criteria:

  • Technical skills.
    Team members must demonstrate development and devops abilities on basic and complex tasks.
  • Time management and spillovers.
    Newcomers must have at least half of their sprints clean during their initial trial (2/4), or two thirds of their sprints clean for extended trials (rounded down, eg. 5/8). Confirmed core team members are expected to have at least 75% of their sprints clean. Sprint status is documented on the Sprint Commitments spreadsheet (linked from each cell's weekly sprint meeting).
  • Communication.
    See Roles: Communication for the expected response times, and the additional expectations for Newcomers.
  • Adaptability.
    Team members should respond gracefully to changes in task requirements and scope, communicate concerns and issues, and allocate effort appropriately across the current or follow-up tasks.
  • Potential for growth.
    Team members should demonstrate an enthusiasim for learning and improvement across all aspects of their work.

Here is some more detail about things the core team look for when evaluating newcomers:

  • Delivering On-Time: Avoiding spillover and delivering on schedule is really important in an environment where we make direct promises to clients about deliverables. Our reputation as an organization is on the line when we cannot deliver as we promised, so it matters tremendously to us to see a newcomer making deadlines consistently. It's required that you communicate explicitly when you feel there is going to be spillover, as soon as you can detect it, and try to find someone else who can complete or help you complete them. It’s totally ok to do this, and even welcomed by people who have time left in their sprint. We are a team, and we work together to avoid spillover.
  • Communication: As stressed above, as an international remote team, there is little progress we can make if we don't constantly communicate (with respect to not being interruptive if it isn't necessarily urgent). We promise you that we didn't recruit any mind readers! We won't magically figure anything out unless it's been talked about, through any of our multiple modes of communication. You should be communicating with your reviewers daily or every 2 days minimum on what your progress on their task is (by commenting on the JIRA tickets). Even if they have no questions, just stating status is important and can give reviewers/mentors somewhere to jump in and help. On the other hand, when blocked in a task, make sure to reach the reviewer for help. If the reviewer isn't available, you can reach for the sprint firefighters.
  • Show your skills: It's important to take tasks of progressive difficulty, take reviews on too. It's much easier for the core team to review your trial if you have picked varied tasks of different complexity and skillset. We’re looking for a cross-section of tasks across all our required work areas: full stack dev, devops, and ops.
  • "Nice": This point is in quotes because everyone obviously likes being around other nice people, so you'd assume this was obvious. But of course everyone believes, "Yeah, I'm nice!", but it goes a long way to being deliberately nice with your colleagues, and not just believing you are; they will simply enjoy working with you more.

Screening Review#

For the first complete sprint the newcomer is at OpenCraft, her/his mentor will schedule a screening review task assigned to himself and at least two other core members as reviewers. They'll evaluate the work of the newcomer in his first complete sprint and decide if the trial should go ahead.

End of trial, extensions and developer review schedules#

When a newcomer first joins OpenCraft, we set a date for the end of the trial and a cutoff date for developer reviews. The end of a trial is calculated taking into consideration the date the newcomer started working at OpenCraft and is based on the current practice of a four sprint trial period. This means the end of the trial date is exactly 56 days after the starting date.

end_of_trial = start_date + 56

To make sure the developer reviews are completed in time for a fair discussion, these must be completed at least seven days before the end of the trial or 7 weeks after the start:

review_deadline = end_of_trial - 7 = start_date + 49

In case the core team decides to accept the newcomer or to end the trial, the process is complete.

The core team can also choose to extend the trial period for two or four sprints, starting a new process similar to the original end of trial and developer reviews.

Similar to the original end-of-trial developer review, there will be an end-of-extension developer review. Depending on the duration of the extension, the end date of the extension will 28 or 56 days from the date of the 121 when the newcomer received the feedback and was notified about the extension:

end_of_extension = date_of_121 + 28
# or
end_of_extension = date_of_121 + 56

Again, the developer reviews deadline must be seven days before the end of the extension.

review_deadline = end_of_extension - 7

Special attention must be paid to the end of the trial and the end of the extension when the newcomer didn't start working at OpenCraft at the beginning of a sprint. In such cases, the review tasks may have to be scheduled a sprint earlier than expected to give enough time for any discussions.

In cases the newcomer joined at the beginning of a sprint, the developer reviews tasks must be completed in the first week of the last sprint of the trial/extension, with the second week for discussions.

Other references#

See also:


Sales and Business Development at OpenCraft is primarily driven by building a solid reputation for our services that ripples out into referrals who we then court.

That is not to say that advertising does not play a role in our overall marketing strategy, or that marketing overall is not important. However it does mean that our approach to handling sales and business development is in alignment with our values of openness, quality, and commitment. Of particular usefulness during sales is our quality of empathy: Not only is it important to understand how we can help our clients achieve our goals, it is also important to know when we are not the best fit for a client's needs.

We do not make promises we cannot keep. We set realistic expectations with prospects about what we will deliver, at what cost, and when. We are leaders in our field and do not skimp on quality.

Lead Prioritization#

If you have been working at OpenCraft for a while, you may have noticed the time spent on automation, the care given to individual members, and the work done to avoid 'crunch time' in favor of more sustainable paces of development. This allows us to deliver the level of code quality we want alongside solid reliability.

Much of our pricing builds in buffers to handle issues before they come down 'to the wire', but this also means that our level of service is outside the budget of most leads. Our style of work is best done with clients who share our values, and we love to work with those that have great ambitions for their projects.

These factors, and a few more, compose our 'Lead Prioritization Rubric'. This rubric entails the factors we use to determine if a lead is a good fit for us, and how much effort will be spent trying to work with them. Note: These criteria are primarily for determining how much proactive investment will be performed to gain an institutional customer. Many customers may still be a good fit for our Pro & Teacher plan, which is our Software as a Service solution anyone can sign up for and use.

There is, of course, some risk of publishing this rubric-- if potential clients know what our criteria are, might it be seen as gauche. However our belief in openness drives our decision here: If a client reads this rubric, they may know for themselves whether we are a good fit for their organization. Most will not, but if you're the sort of potential client curious enough to read our manuals-- Hi! You sound like you might score well on our 'people profile' factor :)


The lead prioritization rubric is built from seven factors. Each factor can have a scoring of 0, 1, or 2. Each factor also has a weight multiplier. Some factors are worth twice as much. Others are worth three times. After all factors are considered, we reach a composite score, which can then be used to determine how much time and energy we will put into a potential project.

Factor 2 points 1 point 0 points Weighting
People profile Client is competent and knowledgeable enough not to make unrealistic demands regarding deliverables and timeframes. They share our values, especially in regards to open source and contributing code upstream, quality, transparency, and empathy. Awareness of the value of open source and its community. May be involved in altruistic work that helps the local or global community. No indication that they're oriented to open source, try to maximize what can be kept closed. Difficult to work with. 2
Need Compelling business need, a project critical to their business/survival. Possibly a long term recurring need for the client that supports our long term growth. Project would address a medium-level need that is important but not urgent. Importance unknown or potentially a side project that doesn't matter for their bottom line. If a project ensues, most likely would be a one-off, with long term work to be assumed by their internal team. 2
Budget They are comfortable with our institutional pricing, including standard monthly maintenance fees and hourly rates for support and development. There is a confirmed budget and they will be reasonable with what they expect from that budget, or ready to listen and downsize their ambitions to match what they can afford. Have indicated they can afford standard quoted prices. Expressed reluctance or surprise at our pricing structure. 2
Contract Type Institutional with Blended hourly rate. Willing to work iteratively, with a set monthly hours budget, adapting their scope progressively over time, and matching our preferred way of working. Institutional hosting plan with fixed pricing Pro/Teacher plan with fixed pricing 1
Prestige A leading organization in their field that is well known within their industry (or even beyond) and which would be a valuable reference. Moderately known in their domain with some reference value, or a referral from an important client like edX, Harvard, MIT, etc. Relatively unknown except within their geography or field. 3
Market Niche The customer requires a solution that is:

1. Ambitious -- either hosting many, many users or providing unique experiences and functionality.
2. Worry-free -- happy to invest as needed to make sure it will never bother them in the middle of the night or make them wonder if the task will get done right.
3. Requires a lot of coordination, planning, and solid communication within the community. We know the community in and out and the community knows us. We have consistently worked to hash out requirements for the group at large.
We can help but so can others. There will be work to do to demonstrate how OpenCraft's unique capabilities can better serve the customer. Customer can get what they think they need from others more cheaply. No unique capability alignment. 2
Internal positive bias Validated internal champion/supporter for OpenCraft;demonstrated propensity to adopt Open edX Possible pro-Open edX bias. Potential emerging champion for OpenCraft. No indication of a positive bias toward Open edX or there's a steep hill to climb to garner decision maker support. Possibly inclined to build their own homebrewed solution that doesn't involve Open edX. 2

The composite scores fall within three ranges:

Category Score Range Stance
High Priority 20-28 Aggressively pursue this highly viable and desirable lead! Invest in technical discoveries at no upfront charge.
Medium Priority 10-19 Pursue. Actively follow up with lead and offer to perform paid technical discoveries.
Low Priority Below 10 Pursue if time allows or when factors improve.
Example scoring#

Here are a few imagined scenarios and how the rubric works with them.

Hedera University#

Hedera University is a well known institution whose students are selected through a rigorous admissions process and which has a reputation for innovating in education. The university has decided to start offering micro-degress that carry its name and use their content but which do not require the same level of financial investment as its in-person courses. Normal tuition for Hedera University is near the cost of a house each year.

Jimmy from their curriculum department has heard of us from one of their competing universities and knows we're the best in the field. He has reached out to us to build their microdegree project, but isn't a software person. He's heard of Open Source, and knows Open edX is open source, and has an understanding that this means that anything can be changed. People from his team have asked about hours spent contributing code upstream and don't have an understanding of the reduction in maintenance costs this brings.

This is a long-term project-- they'd like to build an ecosystem around their microdegree program with special showcasing and sharing to business partners for hiring. It also needs to integrate with their existing services/authentication systems.

Factor Comment Score Weighted Score
People Profile They have some understanding of open source but they're not so experienced in being contributors. Their values aren't too far from ours but it's not a perfect fit, either. 1 1 * 2 = 2
Need Hedera University will probably lose out to some other universities also creating microdegree programs, but they have a very solid offline school program that people are willing to take a second mortgage over. 1 1 * 2 = 2
Budget They clearly have the means and have only ever commented on hours spent in terms of not understanding 'why' some are spent where, not on their ability to pay. 2 2 * 2 = 4
Contract Type This involves custom work and hosting their own copy of the platform. It will take months of work to make their ecosystem add-ons. 2 2 * 1 = 2
Prestige Everyone knows who Hedera University is! (Or so we shall pretend). They're huge, and a degree from them gets you into top paying jobs. 2 2 * 3 = 6
Market Niche With as big of a project as this is, and as much integration as it will take, we're the best fit for this project. 2 2 * 2 = 4
Internal Positive Bias Jimmy likes us and is convinced we're the right group for this job. 2 2 * 2 = 4
Total: 24

This lead lands in our 'High Priority' category. We should do everything we can to close this sale!

Affogato International#

Affogato international is an organization dedicated to spreading the wonders of coffee espresso desserts to areas that have previously been unable to afford such decadence. They were featured in a magazine once.

As a non-profit organization, they don't have the budget that some bigger entities have, but their commitment to deliciousness has elicited enough donations to allow them to afford a solid e-learning platform to teach remote learners how to make drinks which expand the mind and the waistline. They don't need much special customization and their courses are very basic but they do have a lot of interested learners-- around 1500. They don't seem surprised when we tell them what their budget will cover and what they can expect from it.

They're looking at a few different LMSes, but they are learning toward us because Open edX is open source. They like that there's a community benefit. Juxtaposed with their judicious use of java, that jives.

Factor Comment Score Weighted Score
People Profile They are enthusiastic about open source and like the community benefit it brings. They may not be software-centric but they have quite realistic expectations about their budget. 2 2 * 2 = 4
Need They have operated so far without an LMS, but having one would greatly improve their reach in coffee education. 1 1 * 2 = 2
Budget They do have the money needed to afford our institutional plan but won't be contracting for much additional development. 1 1 * 2 = 2
Contract Type As mentioned, they're looking for an institutional plan, but not custom dev. 1 1 * 2 = 2
Prestige They're somewhat known but aren't especially well known outside of their sphere of influence. 1 1 * 3 = 3
Market Niche There are other providers that could handle their LMS needs, and while they have many users, it's not too high of an amount and they're not using anywhere near the capabilities of the platform. 0 0 * 2 = 0
Internal Positive Bias There's not a point person that is championing us in particular, but they seem to like us conceptually and we may be able to find one. 1 1 * 2 = 2
Total: 18

This lead fits in our 'Medium Priority' category. There's a decent chance we can close on this sale, so it's worth pursuing, just not with the fervor of the higher priority leads.

Ms. Brown's 5th Grade Class#

Ms. Brown is trying to work computer literacy in with her other educational aims. She doesn't have more than one classroom at a time, but does take them to the computer lab at least once a week for typing and other computer skills. She would like to use some of that time to perform assessments that can be instantly graded via the platform. It's not clear whether she's paying for it out of her school budget or her own pocket, but she can afford the monthly cost of a P&T instance.

When she was younger, she took a course on and heard that it was possible to get a copy of that software to use for your own courses. So she looked up on their website and found us, and reached out to ask if we offer any discounts for public school teachers.

Factor Comment Score Weighted Score
People Profile Ms. Brown hasn't shown any particular propensity toward Open Source. We don't have much information to go on here, overall, so we award no points. 0 0 * 2 = 0
Budget She is not in a position to do custom development, and has a small budget. She is able to afford a P&T instance, however. 0 0 * 1 = 0
Contract Type Ms. Brown is not looking for an institutional-level plan, but is a good fit for P&T 0 0 * 2 = 0
Prestige Ms. Brown is a public school teacher, and is not an organization with any particular visibility. 0 2 * 0 = 0
Market Niche Ms. Browns needs are very straightforward-- just performing mini-lessons and assessments with her students. There are other providers who can do this for her readily, though we can also address this with P&T. 0 0 * 2 = 0
Internal Positive Bias Ms. Brown likes Open edX and is very familiar with it. She is hesitant to choose another LMS when this one works. 2 1 * 2 = 2
Total: 2

This lead fits into our 'Low Priority' category, as we're focusing on institutional customers for the bulk of our sales team's time. Directing her to our P&T plan would be our best bet, as it should be better for her budget and needs and can be set up without team intervention.

Prospect Intro Meetings#

As part of qualifying leads and better understanding how we may meet the needs of clients, initial introductory meetings are scheduled.

Meeting Preperation#

Before the meeting, search for information on the client online. Most organizations will have a website where you can learn about who they are and what they do. Looking up the contact's information on LinkedIn is also helpful.

Things to keep in mind when looking up the client's info:

  1. Situation: What is the organization like? What do they do? Do we know of any trends or changes to their sector that may be affecting them?
  2. Problem: Based on what they may have already communicated, or what you can infer from your experience with similar clients, what kinds of challenges might they be facing?
  3. Implications: How might these problems be impacting what they're trying to accomplish as an organization?
  4. Need Payoff: How might OpenCraft be uniquely suited to addressing their challenges in a way that helps them be more successful?

Spend some time ruminating over this information and bring it to the meeting. You can quickly build rapport by speaking to their needs. Write up what you find in an update on the CRM.

Meeting agenda#

While these meetings are fluid and should not have a strict structure, there are some helpful anchor points to keep in mind.

  1. If you're not sure how familiar the client is with OpenCraft, ask if they'd like a basic rundown of who we are and what we do. If they say yes, give them a basic introduction, going over these points:
    • Our experience and knowledge of the Open edX platform
    • Our involvement in the Core Committers program
    • Our commitment to Open Source
    • A summary of clients we work with
    • The volume of contributions we've made (and continue to make) to the platform
  2. Preferably, you'll have already read up a little on their organization. Ask them about it, especially any specific questions you may have come up with when browsing their website.
  3. Ask about the problem they're trying to solve.
  4. At some point in the meeting (if it doesn't come up in 1), be sure to mention our policy of upstreaming contributions. The earlier we can gauge the client's appetite for open source, the sooner we can determine their people profile, and whether they'll be asking us to work under terms we'll accept.
  5. If they have not tried Open edX yet, suggest that they sign up for the P&T trial so they can play with the software and see how it works. If you think it would be helpful, or if they've asked for a walkthrough, bring up the demo instance and show them around.
  6. Determine next steps and lay them out for post-meeting follow-up. This might be getting them to send a detailed list of requirements, or starting the discovery process. If starting a discovery, make sure to get them to agree to pay for the time spent on discovery. If they're a high priority lead, this cost can be deferred until they agree to start the project-- though you may have to guess at this point if you haven't already run the rubric.

When the meeting is finished, write an email to the client summarizing what you went over in the meeting, and what the next steps are. Create tasks as necessary and update the prioritization for the lead in the CRM so you can remember to check in later if they don't respond. Add an update to the lead, as well.

OpenCraft's Customer Lifecycle#

What is it?#

The OpenCraft customer lifecycle is a process that defines how we work with customers. It describes the steps of our client’s journey, beginning as a sales lead and progressing through a sequence of discrete stages until they become a paying customer. It defines our objectives as well as recommended activities at each stage as well as the tools and resources to help us achieve these objectives. There are gates between each stage that describe what customer behaviors should occur before an opportunity can advance from one stage to the next. The customer lifecycle should clarify how we can work together to advance sales opportunities and make our interactions with customers more consistent and effective. These guidelines are a living document that is periodically enhanced and updated with the teams' ideas and suggestions.

The following figure provides a visual summary of the stages of our customer lifecycle:


Customer lifecycle: Stages#

1. Generating Leads#
What is it?#

At this stage, we create demand for our services through demand generation, and try to generate opportunities.

Lead generation consists in conducting activities that will generate demand for our services. This includes marketing activities and community involvement.

What activities are involved (and who does them)?#
  • Preparing blog posts (everyone)
  • Preparing the monthly newsletter (marketing specialist)
  • Helping community members on the official Open edX forum and Slack team (everyone)
  • Hosting talks at the annual Open edX Conference (everyone)
  • Social media: sharing blog posts, community news, etc. (marketing specialist)
  • Community involvement: attending working group meetings, community meetups, workshops, doing code reviews and platform contributions, etc. (everyone)
  • Sending cold emails (bizdev):
    • To attendees of the annual Open edX Conference
    • To the attendees of the annual edX Partners Forum
  • Subscribing to RFP alerts using keywords (bizdev)
What resources and tools are used?#
  • (TBD) A "developer's playbook" for prospecting within existing accounts
  • List of attendees for Open edX community events (conference, meetups, workshops, etc.)
How does the opportunity advance to the next stage (stage gate)?#

Someone inquires about our services (and becomes a Lead)!

2. Prospect Qualification#
What is it?#

At this stage, we determine if a lead is a good fit for us, and how much effort will be spent trying to work with them. This process, called "qualification", is all about gathering insights necessary to make a good judgment.

What activities are involved (and who does them)?#
  • Keep a lookout for new potential projects with contacts and within current client organizations (bizdev, developers)
  • Greet our leads, and send them our standard hosting/support quote (bizdev)
  • Assess public Requests For Proposals (RFP) and determine if they're a match
  • Apply the Lead Prioritization Rubric to qualify leads and determine next course of action
  • Capture information in the CRM (bizdev)
  • Do periodical follow-ups (bizdev)
What resources and tools are used?#
How does the opportunity advance to the next stage (stage gate)?#
  • Opportunity is scored as high or medium priority in the Lead Prioritization Rubric
  • Lead is responsive, and becomes a serious prospect
3. Assess Needs#
What is it?#

In this stage, we learn enough about the customer to enable OpenCraft to create a compelling proposal. We also ensure that the opportunity passes a higher stage of qualification.

We need to get a clear understanding of: * The customer’s challenges and business issues * A high level outline of the solution the customer needs to address their current challenges * Functional and technical requirements for the solution * The client's internal decision-making process * Potential alternatives (other product, internal solution, etc.) and competitors, strengths and weaknesses relative to OpenCraft

What activities are involved (and who does them)?#
  • Identify and meet with key stakeholders to gather above information (bizdev, dev)
  • Use additional information gathered to revisit the Lead Prioritization Rubric to assess how the lead qualifies, based on:
    • Ability of prospect to pay for the discovery work and is comfortable with our hourly rates
    • Customer’s need is compelling and something we can address in a unique way
    • Prospect is competent, reasonable and is aligned with our open source / upstreaming approach (bizdev)
  • Capture information in the CRM (bizdev)
What resources and tools are used?#
How does the opportunity advance to the next stage (stage gate)?#
  • Information about the Prospect's challenges and needs + value proposition is documented in the CRM
  • The opportunity’s score on the Lead Prioritization Rubric is improving
4. Blueprint#
What is it?#

In this stage, we use all the information that we captured to prepare a project blueprint that maps to the prospect's needs, budget, and timeline.

The project blueprint contains: * A description of the solution designed by OpenCraft * Acceptance criteria * Tasks and estimates * A project timeline

What activities are involved (and who does them)?#
  • Schedule necessary discovery tasks (bizdev)
  • Prepare project blueprint (often also called a "discovery report") (dev)
  • Communicate with prospect as needed during the discovery (bizdev, dev)
  • Capture information in the CRM (bizdev)
What resources and tools are used?#
How does the opportunity advance to the next stage (stage gate)?#

A project blueprint has been completed.

5. Proposal#
What is it?#

In this stage, we prepare and present a comprehensive proposal demonstrating the proposed solution, scope, budget, and timeline. The proposal comprises the project blueprint and a financial quote.

What activities are involved (and who does them)?#
  • Review the project blueprint (bizdev)
  • Prepare a quote (bizdev)
  • Offer to book a proposal presentation with prospect (bizdev)
  • Prepare proposal presentation (bizdev)
  • Attend proposal presentation meeting (bizdev + dev (if applicable))
  • Send quote + blueprint to prospect after the presentation (bizdev)
  • Adjust blueprint and quote as needed (bizdev + dev)
  • Capture information in the CRM (bizdev)
What resources and tools are used?#
How does the opportunity advance to the next stage (stage gate)?#

We deliver a final proposal to the prospect.

6. Close#
What is it?#

In sales terms, closing is generally defined as the moment when a prospect or customer decides to make the purchase. Some prospects will self-close, and some will require us to instigate the close. When needed, we close a sale by summarizing the benefits and value of our proposal, and prompting the prospect to communicate their decision.

In this stage, the client formally commits to OpenCraft by: * Agreeing on deal contract, including pricing and terms * Sending a SOW (if applicable) * Delivering a deposit payment (if applicable)

What activities are involved (and who does them)?#
  • Summarizing the benefits and value of our proposal, when required (bizdev)
  • Completion of onboarding steps
  • Resolve any outstanding legal and business issues (bizdev, admin specialist)
  • Conduct kickoff meeting (kickoff) (bizdev, dev)
  • Capture information in CRM
What resources and tools are used?#
How does the opportunity advance to the next stage (stage gate)?#
  • The prospect accepts our proposal and becomes a client.
  • All onboarding steps have been completed
  • Kickoff call is done
  • Communication, budget tracking, and project updates are set
  • Epics and tasks are scheduled
  • Deposit payment has been received (if applicable)
7. Development#
What is it?#

The development stage is where the team develops and implements the solution.

What activities are involved (and who does them)?#
  • Executing the technical tasks (dev)
  • Project management, including: stand-up meetings, task-budget-timeline tracking, resolving issues (dev)
  • Prospecting for new opportunities (go back to stage 1) (dev)
What resources and tools are used?#
  • Project tracking software (Jira)
How does the opportunity advance to the next stage (stage gate)?#

We have completed the project (if using a fixed price) or have completed a month of work (hourly project).

8. Billing#
What is it?#

In this stage, we bill the client for the work.

What selling activities are involved (and who does them)?#
  • Upload Jira work logs to Freshbooks
  • Review and send invoices (admin specialist)
  • Budget tracking (dev)
  • Discuss and resolve budget issues (dev, admin specialist)
What resources and tools are used?#
  • Jira
  • Freshbooks


Please find below the description of the process for sprints. While it might sound a bit convoluted, it's pretty simple in practice. We work in two-week sprints. Each cell has its own board, backlog and sprint, but they are all held in sync.

Day of Sprint
Day 0 (Monday) Each cell holds a sprint planning meeting to do a final review of the plans for the upcoming sprint, and start the sprint. We use the Sprints app to plan our team's time (that everyone has enough work and nobody will be overcommitted) and to collectively make sure we're staying on track with each client's monthly budget and each epic/project budget.
Day 0 or 1 Each developer should review every ticket they have in the sprint, to confirm the due date, plan when/how to approach the work, coordinate with the reviewer for time-sensitive reviews, etc.
Days 0-4 Development - each team member works on their tickets and code reviews. Tasks move from left to right until completion on our JIRA tracker.
Day 7 (Monday) Each cell holds a mid-sprint meeting to ensure everything is going smoothly, and discuss how to help with tasks that are at risk of not being finished by the end of the sprint.
Days 7-11 Development continues
Day 10 (Thursday) Each epic owner posts an epic update, which includes creating and prioritizing all tasks from that epic that their cell should work on in the upcoming sprint.
Day 11 (Friday) Cells collaboratively and asynchronously refine and estimate tasks complexity. Once done, they assign tasks and reviews to themselves.
End of day Friday is the deadline for creating and assigning stories to the upcoming sprint, and is also when the asynchronous refinement session is closed.
Day 14 (Monday) Depending on their timezone, some developers may have some time on Monday to finish up development or work ahead before the new sprint starts.

Detailed version#

All Roles#

  • In general, "work from the right" - it's better to finish a task that's already in progress than it is to start a whole new task. This reduces context switching, which will help get things done more quickly. With that said, if you are blocked on a task, move on to another task, until unblocked.
  • Daily, use the Tempo time tracking on the Jira board to record the time spent on each task and update each ticket being worked on once finished on it for the day. Even just a quick summary or sentence of where you're at with the task is useful to your reviewer.

Developer Team#

  • All tasks are split up into epics, and each epic has an "epic owner."
  • Near the end of each sprint, in preparation for the next one, the team will do an asynchronous "refinement" session. This means that we each estimate the complexity of each task in the upcoming sprint in terms of "story points". The person in the cell responsible for the sprint planning is the one who starts this refinement session and invites everyone to it.
    • We use story points as a shorthand for agreeing about the complexity of a task. Story points are meant to be a relatively objective measure of "complexity", and not necessarily indicate how long it would take any particular developer to do.
    • We use a fibonacci scale for story points (please see task workflows for more detail on story points for different types of tasks).
    • If anything about the task or the acceptance criteria is unclear, post a question as a comment on the task and try to work with the epic owner (or the reporter if there is no epic owner) to get it answered before the meeting. Note that during the asynchronous refinement sessions, any comments/questions posted in the estimation session will be lost once the refinement session ends, so it's preferable to post questions on the tickets themselves.
  • Likewise, before the Monday planning meeting, everyone works to asynchronously assign each story in the upcoming sprint to a developer and a code reviewer.
    • The epic owner is responsible for making sure this happens for each story in their epics that must happen in the upcoming sprint. For stories that don't have an epic owner, either the tentative assignee (if there is one already) or the person who reported the ticket is responsible for doing this; this is also documented in our Jira bot Crafty's code
    • Epic owners should also check the Sprints app for the upcoming sprint, ensuring that the tasks the team plans to take on for the upcoming sprint are in line with each client's budget and each epic's budget.
  • We have a meeting on Monday via video chat. There we review the refinement and assignments for the upcoming sprint (please see the sprint planning agenda for details of this meeting).
    • The meeting link is in the calendar invite.
    • If you don't see the meetings as recurring events on your calendar, ask Xavier to send you the invitation.
  • After the sprint has been planned and started, it's time to code! If it's your first sprint, your mentor should have assigned you a task, in addition to the onboarding task.

During the sprint:

  • Take a look at the current sprint board. There are filters at the top such as My Issues, My code reviews, and your name, which can be toggled to show only issues relevant to you.
  • Drag a task from column to column on the sprint board to update its status as you work through it. The various statuses/columns are described below. Tasks move from left to right until completion.
  • In general, "work from the right" - it's better to finish a task that's already in progress than it is to start a whole new task. This reduces context switching, which will help get things done more quickly; it also demonstrates reactivity to upstream reviewers (which pushes them to be reactive too).
  • Use the Tempo timekeeping system built into our JIRA board for tracking the time you spend on each task.

Planning agenda#


Planning for a given sprint is done asynchronously, with the steps happening during the previous sprint. So, in any given sprint, one of the tasks everyone has is to plan for the following sprint.

The steps involved in that planning are described in the sprint planning checklist template, as well as the follow-up tasks to be done during the sprint itself.

Our bot creates a dedicated checklist for each member, every sprint, in the workspace which corresponds to their cell. The checklist is to be completed by all team members during the sprint, according to the timelines described there.

Tentative assignees#

To ensure that tasks lined up for the sprint are all actively being taken care of, from the beginning of sprint planning, some tasks are tentatively assigned by their creator. To show the tentative assignment, these tasks are flagged in Jira (they appear in yellow in the backlog).

The tentative assignee isn’t meant to be necessarily the person who will be actually working on the task. Like for PR reviews, the goal is to ensure proper focus and avoid dilution of responsibility, so we need one specific person assigned to each ticket to do that review early on, even if the actual assignee changes later.

The assignment is done without considering size/availability, since the tickets aren’t yet scoped or estimated. The tentative assignee is merely the person who will be responsible for finding the final assignee, and getting the task through the planning steps in the meantime, such as reviewing the task description.

The tentative assignee is responsible for reassigning and/or rescoping the tickets before the sprint starts. Note that if no action is taken, by default the tentative assignee will become the actual task assignee when the sprint starts.

Estimation session#

The sprint planning manager creates the sprint estimation session in Jira. An email with a link is sent out when the session opens. For each task:

  • Read through the description
  • Decide whether you can take it
  • If you do want it, it's ok to spend a bit more time investigating
  • If you have questions, put them in comments on the ticket
  • Assign points as described in the process section
  • Use the "estimate comments" box to qualify estimates
  • Choose ? if you have no idea how many points
  • A little green (/) will appear next to your picture up top when you are done

Complete the estimation session by Friday. Stay conscious of time budgets and try not to log more than a few minutes per task to do these estimates.

Task insertion#

The following process applies when someone wants to add a ticket to the sprint after the Thursday EOD deadline:

  • If the ticket replaces another ticket already in the sprint, or is split out from one: explicitly reference the ticket being replaced or split out from in the task description, and ping the sprint planning manager for confirmation.
  • Otherwise, place the ticket at the top of the stretch goals, and ping the sprint planning manager to inform of the desire to include the ticket in the sprint if possible. There would not be any guarantee of such an inclusion, but once the sprint is fully ready (ie, all the tickets in the sprint are ready and all the other verifications before the start of the sprint have been completed, including ensuring nobody is overcommitted), then the ticket can be considered for a sprint insertion if someone still needs work. This is handled the same way we would treat a ticket that we want to add in the middle of a sprint.
  • No other exception. A sprint insertion has to follow either of these paths, or it will be moved to the next sprint or the stretch goals.

Sprint video update#

The video updates are a way for us to keep a regular occasion for everyone in a cell to see & hear each other directly on video, rather than switch to 100% textual. They also include an optional text component, that completes the video format as necessary. The updates are posted in a dedicated "Sprint updates" forum thread for the cell, reusing it between sprints.

The update should contain a video recording of 1 to 2 minutes maximum on Loom (credentials) or using the software of your choice such as OBS Studio

  • Share both your screen & camera, and name the video Sprint X - <Cell> - <Your name> with X being the number of the sprint finishing
  • If you use a Loom video, copy the link from the "Send your video" box on the top right of the Loom video page, and place it on a line by itself to ensure discourse shows the video inline.
  • If you create your own video, upload it to the Async planning meeting videos folder, and use an iframe to display the video inline in your post:
  • <iframe src="[hash]/preview" width="640" height="360" frameborder="0" allowfullscreen></iframe>
  • Note that it might be necessary to disable the enhanced tracking protection from Firefox on to play videos embedded this way.
  • [Optional] Include a text update below your video - for example to highlight points that shouldn't be missed, or provide links to elements you mention in your video.

Present the following points in your update:

  • If a newcomer is scheduled to join this week, ensure you've created a quick introductory video of yourself and stored it under your cell in OpenCraft Shared Drive > Meeting videos > Team introductions. Provide your name, how long you have been with OpenCraft, your current location, and an interesting fact about you.
  • Some of your work, in a mini-demo/presentation of what you did during the previous sprint, mentioning any major accomplishments, interesting tickets, lessons learned, or problems encountered that are worth sharing with the team. What has been accomplished, what went well, what went not so well, and the reason for any spillover. Don't just show your Jira board though -- people can already go see this by themselves.
  • Any upcoming vacation if you have some in the upcoming sprint.
  • [Optional] Giving kudos
  • [Optional] Pointing to announcements and discussion started on the forum, introducing them orally when it’s useful.
  • [Optional] If you would like to make an extended presentation or tech demo, which doesn't fit in the 2 minutes of your weekly update, record a separate second video, which you will post in the forum in a dedicated thread. Mention who the intended audience is (the rest of your cell, the whole company, etc.), ask for questions explicitly and come back to the thread regularly to answer them.
  • The sprint firefighter with the rotation on the first week of the upcoming sprint reminds of the theme and time of the social chat they organize this week

Social chat#

With the move to asynchronous planning meetings, we don't get to interact with each other in videocalls regularly anymore! To keep an occasion to do that, and actually make those interactions nicer, we are setting up regular social chats. They are a less formal and utilitarian setting, and are there more to interact with each other in an informal setting, and are optional.

  • They are organized by rotation, and happen every sprint during the first week - every core team member organizes one in turn for their cell, and open to anyone from any cell. We use the firefighter rotation for this, the firefighter for the first week of a sprint posts a topic of their choice and a time (during that same first week of the sprint).
  • Any topic goes, be creative! It doesn't need to be about work (shouldn't be about work?): games, teaching how to prepare a cocktail or recipe, participants showing an interesting place in their neighborhood, etc.
  • The organizer describes the event in a dedicated "Social chat" forum thread for the cell, reused each sprint.
  • The organizer creates a calendar event on the cell's calendar at the time of their choice, and invites all the cell's members as optional attendees. The calendar invite should include:
  • The description/agenda of the event
  • A Zoom meeting URL
  • A link to the corresponding forum post
  • A link to the task where to log the meeting time
  • A mention that the meeting is optional (nobody except the organizer should feel forced to attend, and due to timezones & schedules not everyone will be able to attend every meeting)
  • The 30 minutes are logged on a dedicated task by participants. The organizer creates the task dedicated to a specific meeting when organizing it, including it on a "Social chat" epic, with the "Meetings" account set.
  • Participants can stay longer than 30 minutes at the event if they want to, or attend multiple events from multiple cells, but the time logged is timeboxed to 30 minutes overall. Anyone can leave at any time.

All-hands meetings and tech talks#

From time to time we get together and do tech talks, to share knowledge and as an opportunity to meet members of the other cells. Note that a tech talk can also be contributed asynchronously using the video recording at the end of any sprint.

An all-hands meeting will be scheduled when there's something we want to discuss at the team level, or when there's a tech talk. To schedule a tech talk, create a ticket in your own cell to prepare it, then discuss in the tech talks thread a date that works for all cells (it must be on the same day as a mid-sprint meeting).

Sprint Retrospectives#

Each cell performs a retrospective every sprint. The purpose of the sprint retrospective is to allowed continued improvement on our processes and methods by creating dedicated time for reviewing how each sprint went, and how things might be improved.

Near the end of each sprint, every member is expected to go to the Sprint Retrospective Document and add things which need to be improved and things that went well to their cell's worksheet. After rolling over to the new sprint, the Sprint Manager takes these items and adds them to the cell's running forum thread on sprint retrospectives. These threads are named 'Sprint Retrospective - Cell Name Here'. (Note: At present these threads are private threads, and may not be visible if you are not a member of OpenCraft and logged in.)

In the forum post, the sprint manager may mention the things that went well, and then will mention the things that need improvement. If there are more than two things which need improvement, the Sprint Manager creates a poll for members to vote on to determine what the cell thinks is the highest priority to address. During the sprint, talks begin between on how to address these items, and tasks are created and scheduled as necessary by the participants.

Business Cell Sprints#

The 'business cell', consisting of meta-operatives working on things like billing, sales, and marketing, currently meets synchronously for one-week sprints.

In time, this cell may move to an asynchronous cadence more in line with the development teams, however for the moment it closely mirrors the synchronous sprint planning of old.

Preparing for the Business Cell Sprint Meeting#

Ahead of the sprint planning meeting, look through all of your current tasks and make sure any which have not been updated to their most current state are updated.

Then, look in the backlog. Consider any spillover you may have, and look at the upcoming sprint. If it does not exist, create it. Put any tickets you anticipate working on into the new sprint to reduce time spent planning during the meeting.

Complete the Sprint Retrospective process, adding in items as you see fit to the business cell worksheet. Log your time here.

Business Cell Sprint Planning Meeting Agenda#

The sprint meetings have the following agenda:

  1. Each member gives an overview of what they worked on this sprint, and any items that spilled over and will affect the next one, as well as reasons for the spillover.
  2. Close the current sprint, setting all still open tickets to move to the next sprint.
  3. With the team, look over the items in the upcoming sprint. Take a moment to verify:
    • Each team member acknowledges the workload they're committing to.
    • All tickets have story points, assignees, and reviewers.
    • Ask about vacation or other reasons for reduced capacity. Will this affect the work being taken on?
    • If there is spare capacity and no intentional reduction in hours, work with the team to pull items from the backlog until capacity is reached.
  4. After confirmation on all items above, start the next sprint.
  5. Any final notes/announcements/kudos.
Business Sprint Video Updates#

Like the development cells, the Business Cell members are expected to post video updates to keep the team at large abreast of new developments in this thread. However, since business cell members have one-week sprints instead of two-week sprints, they are only expected to post these every other sprint, at the same time as development cell members post theirs.

This is to make sure that time can be scheduled to run through all updates in one go to reduce context switching among team members.

Taking Decision#

The exact application may vary depending on the context, but the general pattern for taking decisions at OpenCraft should all follow the same base format:

  • Is this a decision that only affects you, or others? If it only affects you, take the decision, and if you think anyone could be interested, let them know about it. Err on the side of over- communicating on this, there is little downside to it, but a lot of benefits.
  • If it affects others besides you, they will need to review it. Prepare a proposal:
    • It's often better to start with the problem and ask for advice or potential solutions from those with expertise or who would be affected.
    • Then prepare the proposal itself, e.g. a pull request for code, or for changes to the handbook's rules;
    • For a trivial decision, a comment in one of OpenCraft's tools (if it happens on a synchronous tool like the chat though, make sure to document this discussion and link to it from an asynchronous tool);
    • For any other matter, describe the decision to take and the options in a Google Doc on the shared folder, and post it on an asynchronous discussion tool, such as the forum or Jira, pinging anyone who you think could be affected by or interested in the change. Also err on the side of over-communicating on this.
  • Participate in the conversation/review if there are comments. Try to address them, until none of the outstanding comments are blocking for the reviewers. The goal isn't full consensus - the reviewers should be mindful of encouraging action, and it is an acceptable result to only address comments up to the point where the reviewer can live with it.
  • If there is disagreement between the proposer and the reviewers, a manager decides: the manager involved in the review or proposal if there is one; if there isn't one, the CTO for technical decisions or the CEO for other decisions. At any point and for any topic, the CEO can take a final decision, and/or stop the discussion; when this happens the CEO explicitly indicates that the use of his "BDFL" powers, to allow to differentiate between a discussion/argumentation and a decision.
  • If there is agreement - which is hoped to be the case for the very vast majority of decisions - then the decision is taken. To make it so, state the outcome explicitly in the discussion thread, or merge the PR if there is one.


Requesting time off#

  • Make sure to book your vacation:
    • For 1 day off, 3 days in advance
    • For 2 days to 1 week off, by Thursday evening of the week preceding the sprint in which time off starts
    • For more than a week off, two weeks in advance.
  • Check the team calendar first to see if anyone else has booked those dates off. To ensure maximal availability and responsiveness within the cell, if the number of persons corresponding to 20% of the cell size (rounded up) are already away on some days, you can't book the same days. There is however a tolerated 1 day/week per person that can overlap. If in doubt, ask Xavier.
  • If you decide to travel and still work, it's useful to let everyone know, but it's not necessary to go through the vacations process. As long as you have a good internet connection and maintain work hours and communication / reactivity levels, you can work from anywhere.

Additional steps for core developers#

  • Check if you need to make any trades on the rotations schedule and if so, get tentative agreement from someone to trade with you. If the spreadsheet doesn't yet cover the week(s) you'll be away, there is a place near the bottom where you can add a note, so that we can account for your vacation when the schedule gets updated.
  • Make sure that the epic reviewer for any epic you own is going to be present and is fully informed so they can take over the epic owner duties while you are away.

Special vacation#

Besides the "normal" vacation, we also offer the following two variants:

  • Reduced time off: A temporary reduction of the number of hours you work each week.
  • Scoped time off: A temporary change of the scope of work you will work on, to reduce availability to/from specific projects, clients or roles. This is usually used to allow to focus on one or several specific projects for a time, or to take time off projects without being fully off.

The same process and limit as for normal vacations applies. Simply also mention the amount of time that you will have available, or your exact scope of work, for that period of time while you announce your vacations.

Sick days#

  • When you are sick and unable to work, let the rest of the team know asap using the Announcements forum category, and let people know where you would need help/cover as much as possible. In particular, mention which tasks are at risk of spillover or have a looming deadline.
  • Then, rest! Don't half work while sick - it will take you longer to recover, and your work will likely not be very good.
  • Note that it is also possible, and encouraged, to take sick days for mental health, when you need it. Just like other sick days, use them to rest and disconnect - don't check emails or tickets!

Announcing your vacation#

  • Once you have confirmed everything, post on the vacation thread on the forum to announce your vacation, including all the details:
    • Dates of the vacation (inclusive - ie May 1-3 would be 3 days off)
    • Who is covering for you, for each active epic, rotation and role you have responsibilities for
  • Add an event on the OpenCraft calendar, for the period of the vacation, with:
    • Your name, followed by a colon
    • Note: if there is another member of the team with the same first name, you need to provide your full name in the calendar events.
    • Whether you are off, or on reduced time (and if so, how much)
    • Example supported formats: John: off, John: available 4h.
    • Note: do not add the reduced capacity events to your off days (e.g. weekends), because then this time will be counted as negative vacations (i.e. extra availability).
    • A link to the forum post
  • Note that the announcement with the proper details is what confirms the vacation time. You are responsible for ensuring that your vacation time respects the rules - if it doesn't, then the time isn't confirmed as off, and the announcement will need to be updated, on both the forum and the calendar. In case of doubt, don't hesitate to ask Xavier for a review.

Vacation checklist#

Checklists to go through before going on vacation for each type of role, as well as checklists for backups of a specific role during the vacation.


  1. If you own any epics, transfer any knowledge needed to the epic reviewer, and make sure they are still prepared to plan/review all the needed stories and manage the epic while you are away.
  2. Similarly, for all of your roles and rotations, identify a backup (and for rotations like firefighting, see if the other firefighter will be off the same days as you), and inform them of the days they will need to cover for you.
  3. The sprint before you are away, check if there are any newcomers reviews coming up during the time you will be away. If so, coordinate with the cell recruitment manager to schedule and send your review early.
  4. At least a few days before, make sure that every task or review that's assigned to you will either be completed before you leave or assigned to someone else while you are away. Ensure that each task won't spill over, and if there is any risk of a spillover, proactively address the situation now by asking for help. If you will be away for an entire sprint, make sure that there will be absolutely no tasks or reviews in that sprint that are assigned to you, including tasks waiting for upstream review/blockers.
  5. The day before you leave, make sure to set a vacation responder indicating dates you will be unavailable and an alternative person and / or email to contact in case of urgency (notify the person(s) covering for you). Instructions for setting a vacation responder in Gmail
  6. Complete all items on the sprint checklist. The deadlines on the checklist are the final cutoff times, but items can be completed ahead of time. If there is any work you absolutely will not be able to complete for the checklist, talk with the Sprint Planning Manager about having it delegated.


A) Before going away#
  1. Warn:
    1. Team: send an email with the dates and give/remind emergency contact info
      1. Including CTO as backup
      2. If Business Development Specialist will be away at the same time, ask Marketing Specialist to monitor contact@
    2. Clients & prospects, as necessary
    3. Accountants & lawyers, as necessary
  2. Meetings:
    1. Schedule a preparation meeting on the last day with the CTO
    2. Mark other meetings as "no" and block time in calendar to prevent calendly from adding new meetings
    3. Tell backup what to attend, and cancel others (eg. client meetings)
    4. Set autoresponder, mentioning backup contact
    5. Update the pager schedule
  3. Invoices (team, clients) - check in advance for vacation in the team, to see if some people need to send an invoice earlier
B) Main backup (CTO)#
  1. Announce upgrade to latest version of Open edX if one is released during this period. To prepare in advance, and post on the same or next day it is released, as a reply on the edx-code@ ML thread by edX announcing it, and on the OpenCraft.Hosting newsletter.
C) Backup - Business Development Specialist#
  1. Prospects management: replying, meeting them, providing quotes & terms, scheduling meetings for when CEO is back if needed (via Calendly)
  2. Handle email arriving in


A) Before going away#
  1. List the reponsibilities and tasks of the main backup (see B)
  2. Identify backups & create/clone tickets assigned to them, linked to the checklists on this page:
    1. Main backup (CEO)
    2. Sprint reviewer
    3. Ops reviewer - add to and to the pager
  3. Warn:
    1. Team: send an email with the dates
    2. Each current client in advance, as well as the edX Open Source team; tell them to contact the backup for emergencies
    3. Email: Set auto-responder, mentioning backup contact
    4. Pager: Update the pager schedule
  4. Sprint/epic knowledge transfer:
    1. Review any tasks in "External Review/Blocker" or "Long External Review/Blocked" that are assigned to the CTO and transfer knowledge to someone else on the team
    2. Update each active epic description & write final update in the tickets comments before leaving, for knowledge transfer: status, schedule, plans, concerns, commitments, etc.
  5. Meetings:
    1. Schedule review & pre-planning meeting on the last day (involve sprint reviewer)
    2. Review all upcoming meetings during time off and ask if backup can attend or the meeting organizer knows nobody from OpenCraft can make it.
    3. Schedule review & pre-planning meeting on the last day (involve sprint reviewer)
    4. Ensure time is marked as "unavailable" in Google Calendar and Calendly
    5. Review OpenCraft meeting lead schedule and trade meeting times with others as needed
  6. Prepare an invoice for the current month, if the end of the month (invoice time) will happen during the vacation.
B) Main backup#
  1. Sprint planning:
    1. On Thursday and/or Friday of the second week of a sprint, work with epic owners to review the priority of all tickets in the backlog for the upcoming sprint.
    2. Subscribe to GitHub notifications for each PR attached to issues in "Long External Review/Blocked", so that you know if upstream starts reviewing them.
  2. Sprint supervising:
    1. Check on individual task ETA during sprint to ensure completion
    2. Keep clients informed of progress & answering their questions
    3. Help to unblock anyone who is unable to work on their ticket
  3. Attend meetings with potential or current clients to provide technical insight, planning, and estimates
  4. Handover completed projects to the clients

Business Development Specialist#

A) Before going away#
  1. Warn Marketing Specialist about upcoming prospect work/quotes
  2. Backup for contact@ email : Marketing Specialist, if also on vacation then ask CEO or CTO
  3. Do important client follow-ups, let them know about vacation and who will answer them in the meantime
  4. Last day:
    1. Set autoresponder, mentioning backup contact
B) Main backup#
  1. Answer contact@ emails
    1. Greet leads
    2. Schedule discovery task(s) if needed
    3. Prepare & share quotes
  2. Review all emails in spam folder
  3. Answer emails and support request from Pro & Teacher users

Instance Test Checklist#

Purpose: Things to check after making a deep change on a running instance, e.g. changing or upgrading the MySQL database.

Make sure user registration works#

  1. Register a new user (tip, in case your mail provider supports: use,, ... to not run out of email addresses).
  2. Make sure you received the activation email. If instance is set up to use an external SMTP server (SES, AuthSMTP, ...), verify that the email was actually sent via that external service and not directly from the EC2 instance.
  3. Make sure that the activation link works and uses the correct LMS domain.

Make sure course creation and import/export works#

  1. Log into the studio and create a new course.
  2. Add a new unit to the course.
  3. Make sure the "Preview" link works correctly.
  4. Import the Demo course to the newly created course.
  5. Export the course.
  6. Delete a unit.
  7. Reimport the exported course and make sure the units are back in place.

Test course settings in Studio#

  1. Click the Start Date of the course and modify the Start/End dates.
  2. Fill in or modify other course details. Refresh the page and make sure everything was saved correctly.
  3. Click "Invite your students" and check an email is composed with the course Name and URL.
  4. Click "Settings > Course Team" and "New Team Member". Add your email. Click "Add Admin" on your entry.
  5. Click "Settings > Course Groups > New content group". Add a content group.
  6. Click "Settings > Advanced Settings" and check everything displays. Change "Invitation Only" to "true", save and refresh, making sure the change was saved.
  7. Click "Tools > Checklist" and make sure it displays correctly.
  8. Click "Maintenance" in the top-right menu, then "Edit Announcements". Do not edit the current announcements if this is a live instance. Click "Create new", add a Dummy announcement, Edit and then Delete it.
  9. Click the Studio icon in the top-left to go back, find the Demo course. Use "View Live" to open the course in the LMS.

Test course in the LMS#

Test course content#

  1. Cycle through the options on "View this course as".
  2. Cycle through the units in the course, checking video, transcripts, inline discussions, polls and other XBlocks all work correctly.
  3. Make sure to submit answers to problems and check the Submission History feature works correctly.
  4. Click Bookmark this page on a few units.
  5. "View unit in Studio" link works correctly.
  6. Click the "Course" tab and make sure the outline displays correctly
  7. Click "Expand All" and check all sections and subsections are expanded.
  8. Check units have a checkmark for being already seen.
  9. Test the "Example handout" downloads correctly.
  10. Click "Bookmarks" in Course tools and make sure the previously bookmarked units are shown there.

Test other course content courseware features (some tabs might not be available)#

  1. Move to the "Course info" tab and verify both everything displays correctly and that the "View updates in studio" works.
  2. Move to the "Progress" tab, verify it displays correctly and "View grading in Studio" works correctly.
  3. Check the "FAQ" tab displays correctly.

Test discussions#

  1. Go to the "Discussion" tab and submit a new post, and add an image. Make sure the image is uploaded to S3/ObjectStorage successfully, and is displayed in the post correctly.
  2. Use the Edit, Follow and Report buttons.
  3. Make a search using the search box.

Test instructor tab features#

  1. Go to the "Instructor" tab and cycle through the tabs, making sure all content displays correctly.
  2. Go to "Membership" and add the created user to the course.
  3. Add this used as Staff, Admin and TA.
  4. Go to cohorts, add a manual cohort and add learners to this cohort. Select the content group created in Studio.
  5. On Discussions, set discussions as divided by Cohort.
  6. Query the user enrolled in the course using their email on "Student Admin".
  7. Select "Data Downloads" section. Click the "Download profile information as a CSV", "Generate Grade Report" and "Generate Problem Grade Report" buttons. Make sure the links to the reports works correctly.

Test LMS settings#

  1. Click the top-right menu and make sure the link to the "Dashboard" works.
  2. Select "Account" on the top-right menu. Modify profile information. Press the "Reset Your Password" button and wait for the email.
  3. Check the "Linked Accounts" display correctly, link Google or other account if available.
  4. If available, check the "Order History" displays correctly.

Other tests#

Check Django Admin#

  1. Make sure you can log into Django admin.
  2. Make a change to the test user created for the checklisting.

If using a custom theme#

  1. Make sure the theme looks ok in general.
  2. Pay special attention to discussion forums and the wiki (they are using different layouts that tend to break more often).

If using analytics#

  1. Make sure link from "Instructor" tab points to Insights correctly
  2. Make sure that OAuth between LMS and Insights works.
  3. Make sure tracking logs are being synced to S3. We want to sync tracking logs even if not currently using analytics, because the client might want to use them some day. Note that tracking logs don't rotate until they're larger than 1Mb, so if you want to force rotate them, run:
sudo logrotate -f /etc/logrotate.d/hourly/tracking.log


  1. If the checklisting was done on a customer instance and a test course was created for it, log into the LMS as an admin user. Navigate to the 'Courses' tab in the 'Sysadmin dashboard' and delete the test course. Be careful to delete only the correct test course. Keep in mind there's a discussion to deprecate the sysadmin dashboard so this might not be possible after Ironwood.