DEV Community

Akanksha Trehun
Akanksha Trehun

Posted on

Community Bonding: Before the First Line of Project Code

Coding starts on 1 June. This post is about the three weeks before that — what I did
with them, and what I thought the project was going to be, which turned out to be only
partly right.

How I got here

By the time the accepted projects were announced, I had already sent CircuitVerse about
forty pull requests.

That number sounds more impressive than it is. A lot of them were typo fixes in
documentation and specs — genuinely trivial changes, the kind you send while you are
still working out where anything lives. Some were closed. Some are still open.

But they did their job, which was less about the changes themselves than about learning
the shape of the project: how the app is laid out, what the review process feels like,
which parts of the codebase are load-bearing and which are quiet corners nobody has
touched in three years.

The ones I am actually pleased with came later and were small bug fixes rather than
typos — scoping an assignments index to the current user's groups, removing a duplicate
update! call, adding includes(:user) to some notification callbacks that were firing
N+1 queries.

One of them turned out to be a signpost: a partial unique index on
assignments.lti_consumer_key, because LTI 1.1 launches look assignments up by that
column and there was nothing enforcing uniqueness. That was the first time I read
CircuitVerse's LMS integration properly, months before I proposed to rewrite it.

Turning a proposal into issues

The most useful thing I did during bonding was on 25 May, and it produced no code at
all. I broke the project down into four separate feature issues and filed them:

  • #7405 — upgrade the LMS integration from LTI 1.1 to LTI 1.3
  • #7406 — roster sync, so a class list flows from the LMS into a CircuitVerse group
  • #7407 — grade passback via Assignment and Grade Services
  • #7408 — deep linking, so an instructor can embed specific CircuitVerse content in a course page

A proposal is a document you write for a small audience during a selection process, and
then it mostly sits still. Issues are different. They live in the repository where the
work happens, anyone can comment on them, and they force you to state what you are
actually going to build in terms a maintainer can disagree with before you have built
anything.

Writing them also clarified something for me. In the proposal, "LTI 1.3 support" was one
line item. Split into four issues, the dependency structure became obvious: the launch
has to exist before grades can flow back, because grade passback needs the deployment
and resource-link context that a launch establishes. Roster sync and deep linking both
need the same. #7405 is not one of four features, it is the foundation the other three
stand on.

That ordering shaped everything since.

Reading the code I was proposing to replace

The other substantial piece of bonding was reading CircuitVerse's existing LTI 1.1
integration line by line — the controller, the score submission service, the launch
views, the specs.

I went in expecting to find it neglected, because 1.1 is the old standard and my project
is the new one. That is not what I found. It is compact and it works, and it is used by
real courses today.

I did find things I noted for later. Grades were being pushed to the LMS before being
saved locally, so a failed local save could leave the gradebook holding a score
CircuitVerse never stored. A NameError in a code path that only triggers under
specific conditions. Small gaps, mostly in error handling rather than in the happy path.

Two of them became my first pull requests of the coding period.

Reading it also settled a design question I had been vague about in the proposal.
Nothing about my project requires removing 1.1, and plenty of institutions are still on
it. So the plan became strictly additive: 1.3 arrives alongside 1.1, both work, and
nobody's existing setup breaks. "Backward compatible" stopped being a nice phrase in a
proposal and became a constraint I could check every change against.

The Mergathon

On 26 May, CircuitVerse ran a Mergathon — a coordinated push across all the org's
repositories to deal with the pull request backlog. I spent the day on triage.

I have permissions to label, close and comment, not to merge, so the work was: read
every open PR, work out whether it was still alive, and close the ones that were not
with an explanation.

The numbers were bracing. On the Interactive-Book repository I closed around forty-six
stale pull requests, some open since 2019. Thirteen more on the Vue frontend, five on
the blog. On the mobile app there were ten Dependabot PRs all failing for the same
reason — a dependency requiring a newer Flutter SDK than CI was running — so I traced
the root cause once and commented it on all ten. A handful of others were genuinely
green and just needed someone to say so, which I labelled for a maintainer to merge.

Reading dozens of dead pull requests in one sitting is an unusual way to spend a day and
I learned more from it than from anything else in bonding. Almost none of them died
because the code was wrong. They died from going quiet — the author moved on, the branch
drifted behind master, a maintainer asked a question that was never answered, and then
too much time passed for anyone to want to pick it up.

The pattern I noticed and did not fully absorb: the bigger a pull request was, the more
likely it was to be in that pile. Small ones either merged or got closed quickly. Large
ones lingered until they were unmergeable.

I understood that as an observation about other people's pull requests. It took until
week 3 of the coding period, and having my own large one closed, to understand it was
about mine too.

Setting up something to test against

The last piece was practical: getting an LMS I could actually launch from. Reading the
LTI specification tells you what the protocol says. Watching a real Canvas instance
refuse your launch for reasons the spec does not mention teaches you a different set of
things.

This took longer than expected, which I gather is normal. LTI is a protocol where two
servers have to agree about URLs, keys and identifiers before anything works at all, and
every mismatch surfaces as the same unhelpful failure.

What I expected to be hard

Going into 1 June, I thought the difficulty of this project was the protocol —
signatures, key rotation, the security model, getting the cryptography right.

Some of that has been hard. But the protocol is a written specification with a right
answer; if you read it carefully you converge on it.

The part I did not budget for is the one this whole first stretch has actually turned
on: getting the work into a shape somebody else can be confident about. That is not in
any specification, and it is not something I understood until I had done it wrong.

Next: week 1, and actually writing some code.

Top comments (0)