Inspiration

Teams already write decisions down. Confluence has decision items, decision logs and ADR templates, and good teams use them. The failure happens later: a new issue arrives ("Migrate the session store to MongoDB"), the person picking it up was not in the architecture review, and nobody connects the issue to the page that ruled MongoDB out. The decision gets reversed by accident, and the team pays for it twice: once to build the wrong thing, again to argue the decision a second time.

Codegeist asks for apps that use context to help teams ship with confidence. The most expensive missing context we kept seeing is "what has already been decided". So Precedent puts that context on the issue itself, before work starts.

What it does

Precedent is a Forge app for Jira and Confluence.

On every Jira issue, Precedent sits in the issue sidebar. Even collapsed it shows a lozenge such as 1 conflict, so nobody has to remember to check. Expanded, it lists the recorded decisions that relate to the issue, each with a verdict and the reason:

  • Possible conflict: the issue adopts something a decision ruled out, or removes something it chose. Example: "Migrate session store to MongoDB" against the decision "Use PostgreSQL for all new services instead of MongoDB".
  • Check: the issue mentions an option a decision ruled out, without clearly adopting it.
  • Open question: the topic was raised but never decided, so the work may need a decision first.
  • Superseded: the matching decision was replaced (for example ADR-007 superseded by ADR-012), so the team should follow the newer one.
  • Aligned and Related: the issue follows a decision, or shares its topic.

Every decision is quoted word for word with its page, space, section, last editor and date. From the panel you can link the decision page to the issue, and mark the precedents as reviewed: Precedent adds a comment with the verdicts, the page links and an optional note, so the check is visible in the issue history, and the sidebar shows who reviewed and when. Comments and links never copy the decision text, because people who can see the issue may not be allowed to open the page.

In Rovo, the Precedent agent answers "We want to move session storage to MongoDB. Was that ruled out?" or "What have we decided about feature flags?" by calling the app's actions, quoting the decisions and linking them. It can also record the review on an issue when asked.

Through MCP, the same find-precedents and list-decisions tools are exposed with the rovo:mcp module, so Rovo Studio agents and third-party coding agents can check a plan against recorded decisions before they write code. An open SKILL.md tells those agents how to use the results.

For admins, a settings page picks which Confluence labels mark decision pages (default: decision, decisions, decision-log, decision-record, adr) and optionally limits spaces, runs a connection check, and creates demo content in one click.

Nothing new to maintain: Precedent reads the decision items and ADR pages teams already write.

How we built it

  • Forge modules: jira:issueContext (sidebar, with dynamicProperties for the conflict lozenge), jira:issuePanel and jira:adminPage (UI Kit, native render), rovo:agent, three action modules, rovo:mcp, Forge storage. app.compatibility makes Jira required and Confluence optional, and the backend calls Confluence from Jira with requestConfluence.
  • Finding decisions: two CQL searches as the current user (labelled decision pages, plus pages containing the issue's rarest keywords), then page bodies read as ADF. Precedent extracts native decisionItem nodes (decided or open) with the heading they sit under, and for ADR-style pages the "Decision" or "Outcome" section and the page status (Accepted, Superseded, Deprecated).
  • Ranking and verdicts: IDF-weighted overlap between issue and decision, then wording rules that read what a decision chose ("use X", "stay on X", "chose X over Y") and ruled out ("instead of Y", "we rejected Y", "will not use Y", "retire Y"), and what the issue adopts or removes ("migrate ... to X", "switch ... to X", "replace X with Y"). A conflict needs the whole ruled-out phrase, not one shared word. No LLM runs in the panel, so verdicts are fast, repeatable and explainable; the Rovo agent adds judgement on top of the same evidence.
  • Permissions and trust: every product call runs as the signed-in user, so people only see decisions they can already read. Admin calls are re-checked on the server against the Jira ADMINISTER permission. "Link to issue" re-resolves the decision server-side so the browser cannot inject a URL. Review records live in app storage, not in an issue property anyone with edit rights could rewrite, and hold no personal data: the reviewer is read from the review comment's author. Decision text from Confluence is treated as data in the agent prompt, never as instructions. No external egress, no remote backend: the app is eligible for Runs on Atlassian.
  • Quality: 37 tests with fake Jira and Confluence clients cover extraction, verdicts, setup errors, review records, CQL quoting and demo idempotency. Guards were removed one by one to confirm the security tests fail without them. A login-free check script validates the manifest, runs Forge's client-side linters and builds the UI and function bundles with Forge's own bundler.

Challenges we ran into

  • Cross-product access. A Jira app reading Confluence needs the app installed in both products and the user's consent for each. Precedent turns a Confluence 401/403/404 into a setup message that tells the admin exactly what to do, while a 5xx is reported as an outage rather than a setup problem.
  • Avoiding false alarms. Early rules flagged "Add a read replica to the PostgreSQL database" as conflicting with "We will not store sessions in the primary database" because both say "database". Requiring the whole ruled-out phrase fixed it, and the demo issues became regression tests.
  • Decisions come in many shapes: inline decision items, decision logs, ADRs with a status line, status lozenges, "superseded by" notes, MADR's "Decision Drivers" before "Decision Outcome". The extractor handles each and the tests pin them.
  • Being seen at all. Forge issue panels only appear after a user adds them from the Apps button, which defeats an app whose job is to warn people who did not think to check. Precedent also runs in the issue sidebar, and its dynamic lozenge shows the conflict count while collapsed.
  • Small sites. A relevance cut-off that worked on a big corpus hid the only conflict on a site with a single decision, because IDF is low when there are few documents. Conflicts and checks now always survive ranking.

Accomplishments that we're proud of

  • A complete loop on the issue: see the decision, understand why it matters, link it, record that it was reviewed.
  • One set of actions serving three surfaces: the panel's resolvers, the Rovo agent and MCP clients.
  • A judge (or a new team) can go from install to a working demo in a few clicks with the demo content button.

What we learned

The context that prevents rework is often already written down. The hard part is surfacing it at the moment someone is about to contradict it, with a reason they can verify in one click.

What's next for Precedent

  • Teamwork Graph: follow links from decisions to the people and goals behind them, and show who to ask.
  • Bitbucket: run the same check on pull request descriptions.
  • A "decision drift" report for each space: decisions that recent issues keep contradicting are candidates to revisit.

Built With

Share this project:

Updates

Submission history