Building Lictory: Reviewing Requirements Like Code
On Monday I open-sourced Lictory. It’s a self-hosted work management tool for software teams, MIT licensed, built around one idea: requirements should be reviewed like code.
This post is the why, plus a few technical bits I’m probably a little too proud of.
Everyone read a different spec
Here’s the thing I kept running into:
Rework rarely starts in the code. It starts with a spec everyone read differently.
You know the drill. Product writes a ticket. Engineering reads it one way, QA reads it another. Someone edits the description later with “just a small clarification”, nobody notices, and a couple of weeks later three people are in a call arguing about what “done” meant. Nobody was lazy. The spec just drifted under everyone’s feet.
Code mostly doesn’t have this problem, and not because developers are better people (we’re not). It’s because code goes through review: branches, diffs, approvals, CI. You can’t quietly rewrite something that’s already been approved without somebody seeing it.
So why don’t we do the same for the thing the code is supposed to implement?
The idea: treat the spec like a pull request
In Lictory you propose spec changes on a branch. Product, Engineering and QA each review the parts they own, and every approval is tied to the exact revision it was given on. When the spec is ready, you deliver the work in Lictory itself, or hand it off to Jira Cloud if that’s where your team lives.
Here’s what that looks like on a work item from a seeded demo (all fake data, don’t worry about Acme’s payments):

Now, the three parts I actually find interesting.
1. Approvals that know when they’re outdated
An approval in Lictory isn’t “Engineering said OK at some point”. It’s “Engineering approved revision 1”.
If someone edits the spec after sign-off, the old approval is marked outdated and the review is re-requested. That’s exactly what’s going on in the screenshot above: CHK-1 got revised, so the revision 1 approvals from Engineering, QA and Product are now outdated, and all three are asked to look again.
It sounds almost boring when you say it about code. For requirements, it turns out to be the whole point: the people who signed off always signed off on what’s actually written, not on an older version of it.
2. Readiness is computed like CI
“Is this ready to start?” is usually a vibe. In Lictory it’s a function.
Readiness is computed by a pure evaluator, evaluateReadiness in packages/core. It takes check rules plus evidence and returns pass/fail. That’s it. Being pure makes it easy to test and easy to reason about, and when someone disagrees with the result, they’re arguing with the rules, not with a mood.
There are 5 built-in checks, plus configurable ones. You can add an AI check too, but an AI check can never be the only gate. A model can flag problems; it doesn’t get to decide alone.
A few design choices I spent way too long thinking about:
- The Definition of Ready is versioned. If you make the rules stricter, work that already met the old rules keeps them. Tightening the bar shouldn’t un-ready finished work.
- The policy is Allow, Warn or Block, per project. And it’s enforced by the server when work starts, not just by a banner in the UI that everyone learns to ignore.
- Reaching Ready locks main. Once a spec is ready, changes go back through a branch and review, a bit like a protected branch.
- Jira export only hands off ready items. If you deliver in Jira, Jira only gets things that passed the gate.

3. One capability registry for humans, MCP and the agent
AI in Lictory is optional. If you want it, Lictory Intelligence and agents over MCP can suggest changes, and people approve them. Same flow as everything else: AI proposes, humans sign off.
The part I like is under the hood. The UI, MCP and Litto (the in-app agent) all share one capability registry. Something you can do in Lictory is defined once, and the UI, MCP and Litto all work off that same list.
Which is a bit of a meta joke, if you think about it: three separate implementations of the same feature, slowly drifting apart, is exactly the problem Lictory is trying to fix for specs. I didn’t want it inside the codebase either.
Spaces: docs that know about your work
Not everything is a work item, so Lictory also has Spaces: docs pages with real-time editing and version history.
Type # and you can cite a work item, which shows its live status right in the page. It works the other way too: work items list the pages that cite them. And if you want your docs to get the same treatment as your specs, a Reviewed Space sends page edits through a branch and PR.
Built solo (with some help)
I built Lictory alone, as a student at Sapienza and a software engineer here in Rome. “Alone” with an asterisk, though: my teammates were T3 Code, Claude and Grok Bot.
There’s some irony in building a tool about reviewing changes with AI tools whose changes I spent my days reviewing. I’m choosing to call it dogfooding.
It runs on your own server, and there’s a guided install CLI so you don’t have to piece the setup together yourself.
What’s next
The open-source launch was on Monday, November 9. Next stop: Product Hunt on Friday, November 20.
If you’re looking for an open-source, self-hosted alternative to Jira, Plane, OpenProject or Taiga, give it a try. And if you think the whole idea is wrong, I want to hear that too.
- Website: lictory.com
- Docs: docs.lictory.com
- Code: github.com/chricarp/lictory
- Updates: @lictoryhq on X
See you on Product Hunt! 🚀