Guides

One prompt per app

50 apps, each as a single complete build prompt. Find the one that matches what you need, paste it into your assistant, and follow the guide it came from when you want the reasoning behind it.

50 apps

  1. Finance

    purchase approval workflow

    Route purchase requests by amount and category, hold an approval trail finance can audit, and stop chasing sign-off in email. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The request and where it goes
    
    In this Helix project, build me a purchase approval workflow.
    
    Start with the request itself. Someone asks to spend money, so I need the
    amount, the category, the vendor, when it is needed by, and a business
    justification. Put the justification field above the amount. People write
    better answers when they have not already anchored on a number.
    
    Then the routing. Do not route on amount alone: a small legal spend goes
    to someone who cannot assess it, and a large routine renewal crawls
    through three approvers who add nothing. Route on amount and category
    together, and keep those rules in one place I can edit without asking
    anybody. Show the requester which approvers their request will need
    before they submit it.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The approver's screen
    
    Now build the screen an approver actually opens.
    
    For each request waiting on them, show the request, who asked, what this
    vendor has cost us before, and what similar requests in this category were
    approved at. An approver who has to go and look something up will decide
    tomorrow instead of now, and tomorrow is how approval processes die.
    
    Give them four actions: approve, approve with a condition they type,
    reject with a reason, or ask the requester a question without ending the
    request.
    
    Sort the queue by how long each request has been waiting, not by when it
    arrived. Those are different, and the first one is the one that matters.
    
    ## 3. Nothing stalls
    
    Make sure nothing sits still.
    
    Every approver has a named deputy. If a request goes untouched for a
    number of days I set, it moves to the deputy automatically and both people
    are told. Approval processes do not fail because someone says no, they
    fail because someone is on holiday.
    
    Remind approvers of what is waiting on them, once a day, in one message
    rather than one per request.
    
    Track time to decision per approver and per category, and show it on a
    dashboard. If one step is always the slow one, I want that to be a fact
    rather than a suspicion.
    
    ## 4. The record
    
    Add the audit record.
    
    Every state change gets appended, never edited: who did it, when, what
    they decided, why, and a snapshot of what the request looked like at that
    moment. Requests get edited after approval, and the snapshot is the only
    thing that makes that visible.
    
    Then give me the views built on top of it: everything approved in a
    period, everything rejected and why, and anything approved outside the
    normal rules. That last list is short and it is the one worth reading.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Check the budget line a request is drawn against, and push
    approved purchases through as commitments.
    
    <Okta>. Resolve who somebody's manager is, so routing does not depend on a
    list somebody maintains by hand.
    
    <Slack>. Tell an approver something is waiting, and let them approve
    without opening another tab.
    
    <Google Drive>. Keep quotes and contracts attached to the request, which
    is what an auditor asks for.
    
    <Coupa>. Raise the purchase order once a request is approved, so approval
    and procurement are not two separate acts of typing.
    
    <DocuSign>. Send anything above a threshold for signature and read the
    status back onto the request.
    
    <Google Sheets>. Export the approved list for whoever still wants it in a
    spreadsheet, which is most finance teams.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  2. Finance

    budget vs actuals tracker

    Show budget owners where they stand before the month closes: committed versus actual, variance by owner, and a forecast they can act on. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Budget, actuals, and the number in between
    
    In this Helix project, build me a budget vs actuals tracker.
    
    Every budget report I have ever used tells me what I planned and what has
    been invoiced, and both are true, and the remaining figure is still wrong.
    It is wrong because a signed purchase order is money I no longer have and
    nothing shows it until the invoice turns up weeks later.
    
    So build three things, not two. The budget, by cost centre, owner and
    month, loaded from a CSV to start. The actuals, also from CSV for now,
    with a clear route to pulling them from our finance system later. And
    commitments: approved spend that has not been invoiced, with the date I
    expect the invoice to arrive.
    
    Then show planned, invoiced, committed and remaining together, everywhere.
    Never show the remaining number on its own. It is the one people quote and
    the one that needs the other three next to it.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Reconciling, so nothing counts twice
    
    Now handle what happens when an invoice finally arrives.
    
    Let me match it to the commitment it belongs to, so the commitment closes
    and the amount stops being counted in two places. Match on vendor, amount
    and expected date, within a tolerance I can set, and show me the ones you
    are unsure about rather than guessing.
    
    Two lists I want to see. Invoices that match no commitment, which is spend
    that bypassed the process. And commitments well past their expected
    invoice date, which are either late invoices or work that quietly stopped
    and nobody told finance.
    
    Both are short lists and both are findings.
    
    ## 3. Variance a person can act on
    
    Add the view a budget owner opens.
    
    For each cost centre they own: planned, actual, committed, remaining, and
    the variance as both an amount and a percentage.
    
    Then label each variance rather than leaving it as a number. On track. A
    timing difference, because an open commitment or a known late invoice
    explains it. Or a genuine overrun. Those need opposite responses and a
    plain actuals report cannot tell them apart, which is why every month
    turns into the same meeting.
    
    Sort by the size of the variance in money, not in percent. A 40 percent
    overrun on a small line matters less than 5 percent on the biggest one.
    
    ## 4. Refresh it, and close the month
    
    Two last things, and both are about trust.
    
    Refresh the actuals on a schedule and put the time of the last successful
    refresh on every page. If a refresh fails, say so on the screen. A wrong
    number that nobody knows is wrong is worse than no number.
    
    And let me close a month. Closing freezes the figures for that period, so
    a correction posted later shows up in the current month instead of
    silently rewriting something I already put in a board pack.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Pull posted actuals on a schedule, which is the difference
    between a tracker and a spreadsheet.
    
    <Coupa>. Read approved orders so committed spend appears before the
    invoice does.
    
    <Okta>. Resolve owners to real people and read their department, so a
    variance has a name attached that survives a reorganisation.
    
    <Slack>. Warn an owner when a cost centre crosses a threshold, rather than
    at month end.
    
    <Looker>. Publish the variance view where finance already looks, rather
    than making them open another tool.
    
    <Snowflake>. Read historical actuals for the trend, which the ERP will not
    give you cheaply.
    
    <Google Sheets>. Import the original plan, because the budget almost
    always starts life in a spreadsheet.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  3. Finance

    invoice approval queue

    Match invoices to what was approved, route the exceptions, and stop paying late because an email got buried. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Every invoice in one place, duplicates caught
    
    In this Helix project, build me an invoice approval queue.
    
    Start with intake. Every invoice becomes one record: supplier, invoice
    number, dates, currency, totals, line items, and the purchase order
    reference if there is one. Let me type one in and attach the original
    document.
    
    Before anything else touches a new invoice, check whether we have seen it
    before. Flag it if the supplier and invoice number already exist, and flag
    it if the supplier, total and date are all close to something we already
    have. Show me the suspected duplicate side by side rather than rejecting
    it. The same invoice arriving twice by two routes is the most common
    mistake in this whole process and it costs real money.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Matching, so most invoices never reach a person
    
    Now match invoices against what was actually approved.
    
    I will give you purchase orders with their line items. Match each invoice
    by reference, and fall back to supplier plus amount when the reference is
    missing, because it often is.
    
    Set tolerances in one place I can edit: an absolute amount and a
    percentage, whichever is smaller. Inside tolerance, the invoice clears on
    its own and goes to the payment-ready list. Outside it, or with no order
    at all, it becomes an exception with the reason attached.
    
    Every automatic clearance still writes down what it matched and why. "It
    cleared automatically" is a decision, and somebody will eventually ask
    what it matched against.
    
    ## 3. The exception queue
    
    Build the queue itself, and only put exceptions in it.
    
    Each row shows what the invoice says, what the order said, and the
    difference between them, next to each other. An approver should never have
    to open two documents to find a discrepancy.
    
    Route each type of exception to whoever can resolve that type. Missing
    order, over tolerance, quantity mismatch, unknown supplier, suspected
    duplicate. A single shared pile means everything waits for whoever looks
    first.
    
    Actions: approve anyway with a reason, reject with a reason, send back to
    the supplier, or reassign. Sort by days to the payment due date, because
    paying late is the actual cost of a slow queue.
    
    ## 4. Ready to pay, and the record behind it
    
    Finish with the payment-ready list.
    
    Everything approved and not yet paid, grouped by supplier, sorted by due
    date, with early-payment discount windows flagged before they close. A
    queue that pays on time is table stakes. One that catches the discount
    pays for itself.
    
    Let me export a batch for the payment run and mark it paid so it leaves
    the list.
    
    And keep an appended record of every state change, with who, when, and
    what the invoice and the match looked like at that moment. Give me a
    supplier view too: every invoice from one supplier and its status, which
    is what I need open when they ring.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Read purchase orders to match against, and push the approved
    payment batch back.
    
    <Gmail>. Pull invoices that arrive as attachments, so intake is not
    somebody retyping them.
    
    <Slack>. Tell an approver an exception is waiting, with the discrepancy in
    the message.
    
    <Google Drive>. Keep the original invoice attached to its record for the
    audit trail.
    
    <Coupa>. Read the purchase orders and receipts that three-way matching
    needs.
    
    <Snowflake>. Land cleared invoices next to the purchase orders, so spend
    by supplier and by cost centre is one join rather than two exports.
    
    <Brex>. Match card-paid invoices, which otherwise arrive twice and get
    paid twice.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  4. Finance

    expense policy checker

    Check expense claims against your own policy before a human sees them, so reviewers only look at the ones that need judgement. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The policy, as something you can edit
    
    In this Helix project, build me an expense policy checker.
    
    The most important design decision comes first: the policy lives in one
    file that I can edit, not scattered through the code. Limits change by
    city, by category, by seniority and by season, and a policy encoded across
    a codebase stops being maintainable within a month.
    
    So: a rules file with per-category limits, per-city overrides, the receipt
    threshold, which fields each category requires, banned categories, and the
    date each version takes effect. Load it at runtime so changing a limit is
    not a code change.
    
    Then the claims themselves: claimant, date, category, merchant, amount,
    currency, project, attendees, and whether a receipt is attached. A form to
    submit one, and a list.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Read the claim, do not judge it
    
    Now run the rules, and be careful about what you produce.
    
    Do not give me a pass or fail. For each rule that applies, tell me what it
    checked, what it found, and the gap: "dinner limit for London is 60, this
    claim is 98, over by 38". Write it in plain language. A reviewer should
    never need to open the policy document.
    
    Give each rule a severity, set in the rules file rather than in code. A
    missing receipt is a blocker. Two units over a meal limit is a note.
    Treating those the same trains people to ignore both.
    
    The claim's overall status is derived from its findings, never entered by
    hand. And record which version of the policy each claim was checked
    against, so raising a limit next quarter does not retroactively change the
    history of claims that were assessed correctly at the time.
    
    ## 3. The queue, and the exceptions report
    
    Build the reviewer's queue and put only the ambiguous claims in it.
    
    Clear claims go straight through and never appear. Each item that does
    appear shows the claim, the failing rules with their explanations, the
    receipt, and what this person has claimed recently.
    
    Actions: approve, approve as an exception with a required reason, reject
    with a reason, or send back for more information.
    
    Then the report I actually want: every exception granted, by rule, by
    approver, over time. A rule that gets exceptioned constantly is a rule
    that does not match how the company works, and this turns that from an
    argument into a number.
    
    ## 4. Stop the claim before it is submitted
    
    Last, let a claimant check a draft claim against the policy before
    submitting, with exactly the same explanations a reviewer would see.
    
    Most policy breaches are people not knowing the limit rather than people
    pushing their luck. Every claim fixed here is a claim that never enters
    the queue at all.
    
    Then two small reports: spend by category and team over time, so I can see
    whether the policy is drifting away from what things actually cost, and
    the people who hit the same rule repeatedly. Read that second one as a
    training need, not an enforcement list.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Expensify>. Read submitted claims and write back the check result, so
    reviewers work in one place.
    
    <Brex>. Match claims to card transactions, which catches the duplicate and
    the missing receipt.
    
    <Okta>. Resolve the claimant and their manager, so a claim routes to
    whoever actually manages them today.
    
    <Slack>. Send the pre-submission result to the claimant, which is where
    most breaches get fixed.
    
    <NetSuite>. Post approved claims for reimbursement once the check clears,
    so nobody rekeys them.
    
    <Google Sheets>. Let the policy owner edit limits in a sheet, if that is
    genuinely easier than a form.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  5. Finance

    SaaS spend tracker

    One list of every subscription, what it costs, who owns it, when it renews, and how much of it is actually used. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The register, and the date that actually matters
    
    In this Helix project, build me a SaaS spend tracker.
    
    One record per subscription: vendor, product, what it is for, the owning
    team, a named owner, annual cost, currency, contract start and end,
    whether it auto-renews, the notice period in days, and a link to the
    contract.
    
    Now the important bit. Derive a notice deadline, which is the contract end
    minus the notice period, and treat that as the date that governs
    everything in this app. Sort by it, warn on it, report on it. A calendar
    built on renewal dates shows me contracts I can no longer cancel, which is
    an interesting fact and a useless one.
    
    Let me import from CSV with the column mapping in one file I can edit, and
    flag any subscription with no named owner. Ownerless tools are the ones
    that renew forever, because a shared inbox never feels responsible for
    cancelling anything.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Seats bought against seats used
    
    Now add usage, because total spend is a board number and unused seats are
    an actionable one.
    
    Per subscription, let me load who has a seat and when they were last
    active. Then show seats purchased, seats assigned, seats active in the
    last 30, 60 and 90 days, and the annual value of the difference.
    
    Give me a reclaim list: assigned seats with no activity past a threshold I
    set, grouped by tool, ranked by what reclaiming them is worth.
    
    And flag seats still held by people who have left, if I give you a list of
    current staff. That list should be empty. It rarely is, and it is both a
    cost problem and an access problem.
    
    ## 3. Warn me while I can still act
    
    Build the renewal calendar next, ordered by notice deadline.
    
    For the next twelve months: vendor, annual cost, owner, and days
    remaining. Let me set three warning points, say 120, 60 and 30 days
    before the deadline, each one notifying the owner.
    
    Highlight anything auto-renewing that is already inside its notice window.
    Those are decided, and somebody should know that before the invoice
    arrives rather than after.
    
    When a renewal is decided, record the decision, who made it, the date, and
    the usage evidence as it stood at that moment. Six months later nobody can
    reconstruct why a renewal looked justified, and this is the fix.
    
    ## 4. Find what the register does not know about
    
    Two last reports.
    
    Let me import card and expense transactions and match them against known
    subscriptions by vendor name, allowing for the fact that the names will
    not match exactly. Anything recurring that matches nothing becomes a
    candidate for the register. Show me a review list rather than adding them
    automatically, because a recurring charge is not always a subscription.
    
    Then overlap: several subscriptions tagged with the same purpose, which is
    usually two teams buying the same category separately. That one tends to
    find the single largest saving and it needs nothing more than the purpose
    field I filled in at the start.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Okta>. Read who has an account in each tool and when they last signed in,
    which is where unused seats show up.
    
    <NetSuite>. Pull recurring card and invoice transactions, which is how you
    find the tools nobody registered.
    
    <each vendor admin API>. Read seat counts and last-active dates for the
    tools worth the effort.
    
    <Google Calendar>. Block the notice deadline in the owner's calendar, so
    the decision has time in it rather than an alert on the day.
    
    <Coupa>. Read contracts and renewal terms rather than retyping them out of
    PDFs.
    
    <Slack>. Warn the owner at each lead time before a notice deadline.
    
    <Snowflake>. Keep a dated snapshot each month, so a renewal-over-renewal
    price rise is visible rather than something you notice once.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  6. Finance

    order management tracker

    One record per order from placed to paid, with the exceptions surfaced and the states that actually happen rather than the happy path. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. One record, and the states that actually happen
    
    In this Helix project, build me an order management tracker.
    
    One order record that lives for the whole life of the order: customer,
    order reference, order date, promised date, payment terms, currency, and
    lines with product, quantity, unit price and line total. Keep the
    references into every other system on the same record rather than
    creating a second record per system.
    
    Now the state model, and be generous with it. Placed, confirmed,
    partially shipped, backordered, amended, shipped, invoiced, paid,
    returned, cancelled. Let me edit that list.
    
    Model the messy ones properly. Partial shipment is a state, not a note.
    Backordered is a state, with the expected date on it. Amended after
    confirmation is a state, with a history of what changed.
    
    If a state that really happens has nowhere to live, somebody keeps a
    private spreadsheet for it, and that spreadsheet becomes the real system
    within a month.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Where has it stopped
    
    Build the working view, and put exceptions in it rather than every order.
    
    Surface: orders that have not changed state for longer than a threshold I
    set, orders past their promised date, orders partially shipped with no
    expected date for the remainder, orders shipped but not invoiced, and
    invoices past due.
    
    Sort by how long the order has been stuck, not by when it was placed.
    Those are different, and only the first one tells you where to look.
    
    Each exception routes to whoever can resolve that type, and shows the
    order, its history, and the specific thing that is wrong, on one screen.
    
    Give me a per-customer view too, showing every order and its state, which
    is what you need open when they ring.
    
    ## 3. Amendments, with a history
    
    Handle amendments properly.
    
    When an order changes after confirmation, record what changed, who
    approved it, when, and why, and keep the previous version. Quantity
    changes, price changes, date changes, line additions and removals.
    
    Show the amendment history on the order. When an invoice does not match
    the original order, the answer is nearly always in that history, and
    without it somebody spends an afternoon in three systems finding out.
    
    Handle returns and credits as their own records linked to the order and
    the line, rather than as a negative amendment, so the original order
    stays intact and the return is visible as a return.
    
    ## 4. Reconcile ordered, shipped and invoiced
    
    Add the reconciliation, and do it per line rather than per order.
    
    For each line: quantity ordered, quantity shipped, quantity invoiced, and
    the value of each. Flag any line where those three disagree, with the
    difference shown.
    
    Group the mismatches by cause where you can: short shipped and not
    credited, shipped and never invoiced, invoiced above what shipped,
    returned and not credited. Those are different problems with different
    owners.
    
    Then report: value shipped and not invoiced, which is revenue sitting
    unbilled; average days from placed to shipped and shipped to invoiced,
    reported separately because they fail for different reasons; and orders
    by state over time, so a growing backordered pile is visible before
    somebody complains.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Read orders and invoices, and write back the reconciliation
    result. Usually the system of record for the order itself.
    
    <Salesforce>. Read the opportunity the order came from, and write the
    order state back so the account team can see it.
    
    <Stripe>. Read payment status so paid is a fact rather than an assumption.
    
    <Okta>. Read the team attribute, so the app can keep customer pricing and
    terms to the people who negotiate them.
    
    <Slack>. Tell an owner when an order has stopped moving, with the specific
    reason.
    
    <Zendesk>. Show the customer's open tickets on the order, since a stalled
    order and a support ticket are usually the same story.
    
    <Snowflake>. Land the full order lifecycle with its timestamps, which is
    the only way to see where in the process the time actually goes.
    
    <Coupa>. Where an order is fulfilled by a supplier, read the purchase side
    so the two halves reconcile.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  7. Sales and RevOps

    deal desk discount approval app

    Route discount requests by depth and deal size, give approvers the context to decide in minutes, and keep a record of every exception granted. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The request, and showing the ladder first
    
    In this Helix project, build me a deal desk approval app.
    
    A rep asks for a discount, so capture what the discount actually is: list
    price, proposed price, term length, payment terms, any ramp, committed
    volume, and any non-standard terms. Derive the discount percentage and
    amount from the prices so a rep cannot enter them inconsistently.
    
    Keep the approval ladder in one editable file: tiers defined by discount
    depth and contract value together, each with an approver role and a
    ceiling. Not depth alone. Thirty percent off a small deal and off our
    largest contract are different decisions.
    
    Then do the one thing that changes behaviour: as the rep types the
    numbers, show them which tier they are about to land in and what the next
    tier down would require. A rep who can see that 24 percent clears one
    approver and 26 clears three will usually ask for 24.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The approver's screen, built for speed
    
    Now the screen an approver opens, and treat time to decision as the thing
    you are optimising.
    
    Show the economics: list, proposed, discount as percentage and amount,
    annual and total contract value, term, and margin impact if I give you a
    cost basis. Show what we have sold this account before and what discounts
    they have had. And show comparable deals: what similar-sized deals in this
    segment were approved at, with the median and the range.
    
    That comparables panel changes approver behaviour more than any policy
    document, so make it prominent.
    
    Actions: approve, approve at a lower figure they counter with, reject, or
    ask the rep a question without ending the request.
    
    ## 3. Nothing stalls at quarter end
    
    Route each request through every approver its tier requires, in sequence,
    and stop the chain on the first rejection.
    
    Give every approver a named deputy, and reroute automatically after a
    number of hours I set. Quarter end is exactly when people are travelling
    and exactly when this matters.
    
    Track time to decision per request, per approver and per tier, and put it
    on a dashboard. A desk that takes two days in the last week of a quarter
    gets routed around, and once it is routed around it has stopped being a
    control. That number is the early warning.
    
    ## 4. Turn a quarter of decisions into a policy conversation
    
    Every approval and rejection records who, when, the figure approved, and a
    reason chosen from a short fixed list plus free text. Keep the list to
    about six options and make it editable. Free text alone produces a log
    nobody can summarise, which is why discount policy never changes.
    
    Append an audit entry for every state change with a snapshot of what the
    approver saw.
    
    Then report: total discount granted by quarter, segment, rep and reason.
    Median discount by tier. And a single list of every deal approved above
    the standard ladder, which is where a discount policy review should
    start.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read the opportunity, the account history and comparable
    closed deals, then write the approved pricing back.
    
    <Salesforce CPQ>. Read list price and any ramp structure, so the discount
    is calculated rather than typed.
    
    <Slack>. Reach an approver at quarter end, which is when speed is the
    whole point.
    
    <Okta>. Read the manager chain and group membership, so the approval
    ladder is derived from the real org rather than a hardcoded list of names.
    
    <Gong>. Read what was actually said on the call, which is often the
    justification a rep did not write down.
    
    <DocuSign>. Read whether the quote at the approved discount was ever
    signed, which closes the loop on exceptions.
    
    <Snowflake>. Land each approved exception beside the closed deal, which is
    what turns whether we are discounting more than last year into a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  8. Sales and RevOps

    pipeline hygiene dashboard

    Find the opportunities distorting your forecast, name who owns each fix, and make hygiene a short weekly list rather than a quarterly clean-up. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. What healthy means here, and checking every deal against it
    
    In this Helix project, build me a pipeline hygiene dashboard.
    
    Start with the rules, in one file I can edit, because they are the part
    that is specific to us. Give each rule an id, a description, the
    condition, a weight, and the stages it applies to. Seed it with these:
    close date in the past, no activity in a set number of days, next step
    missing or overdue, too long in the current stage, amount missing or zero,
    and forecast category inconsistent with stage.
    
    Weight them by how much they distort the forecast, not by how easy they
    are to check. Otherwise the whole thing gets dominated by trivia.
    
    Then load opportunities from a CSV to start, with a clear route to pulling
    them from the CRM on a schedule later, and evaluate every open deal
    against every rule that applies. Store the result on the record with a
    plain sentence explaining what is wrong.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The rep's list
    
    Now build the screen that does the work.
    
    Each rep sees only their own flagged opportunities, ranked by forecast
    impact: rule weight multiplied by deal value, weighted higher for
    late-stage deals. Cap the list at a number I set, around ten. Show the
    count of what is below the cap but do not list it.
    
    Each row shows the deal, the specific problem in one sentence, and the
    field that needs changing. Not every rule it failed, just the one worth
    acting on.
    
    Let them fix simple fields right there, and jump to the CRM record for
    anything else. And when the list is empty, say so properly. That sounds
    trivial and it is the reason people come back tomorrow.
    
    ## 3. What a manager opens
    
    Add the manager view, and rank by flagged pipeline value rather than
    flagged record count. A blank field on a tiny early-stage deal should
    never outrank a stale close date on the biggest one.
    
    Per team and per rep: hygiene score, flagged records, flagged pipeline
    value, and the split by rule.
    
    Then the number worth putting in a forecast conversation: total pipeline,
    and how much of it fails at least one high-weight rule. That second figure
    is the honest version of the first.
    
    Highlight deals whose close date has moved more than twice. That is a
    stronger slip signal than any single stale date.
    
    ## 4. Prove it is working
    
    Snapshot the hygiene score per team daily and chart it, so I can see
    whether a clean-up stuck or happened once before a board meeting.
    
    Then, if I give you closed data, overlay forecast accuracy for the same
    periods. Until you can do that, hygiene is a preference. Afterwards it is
    a number, and the conversation changes.
    
    Refresh from the CRM on a schedule, record when the last successful sync
    happened and show it on every page. If a sync fails, say so on the screen
    rather than serving stale data quietly. And send each rep and each manager
    a weekly digest of their current list.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Pull every open opportunity on a schedule, with stage,
    activity and next step, and optionally write simple field fixes back so a
    rep can clear the list without leaving it.
    
    <Okta>. Match the CRM's opportunity owner to a signed-in person and their
    team, which is what lets the app give each rep their own list.
    
    <Slack>. Send each rep their short weekly list, which is what makes the
    data actually get fixed.
    
    <Gong>. Read call and email activity, which is a truer engagement signal
    than a logged task.
    
    <Snowflake>. Read historical pipeline for the trend, since the CRM only
    holds the current state.
    
    <Looker>. Feed the team view into the weekly sales dashboard, so hygiene
    sits beside the number it distorts.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  9. Sales and RevOps

    quota and territory planner

    Split accounts into territories, load quota against them, and see the coverage and fairness of a plan before you commit to it. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The account list and the territories
    
    In this Helix project, build me a territory planner.
    
    Start with the part I argue about most: which accounts sit in which
    territory.
    
    I will upload a CSV of every account we could sell to. It has the
    attributes we actually segment on: industry, employee band, revenue band,
    country, region, whether they are already a customer, what they spend
    today, and an estimate of what they could be worth. Read the headers and
    tell me which ones you did not recognise rather than dropping them
    quietly.
    
    Then let me define a territory as a rule over those attributes, not as a
    list of account names. "EMEA, enterprise band, not already a customer"
    should be a territory I can write once and have new accounts fall into on
    their own. I also need a small exceptions list for the accounts that have
    to be placed by hand, and every exception has to carry a reason.
    
    Show me, per territory: how many accounts, what they are worth today, and
    what they could be worth.
    
    Two lists matter more than anything else on this screen. Accounts matched
    by two territories, and accounts matched by none. Put both where I cannot
    miss them.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. If you need to reach Salesforce later, tell me and
    I will create the connection in my workspace rather than putting a key in
    the code.
    
    ## 2. Quota that belongs to the territory
    
    Now add quota.
    
    For each territory I want to enter four things: the existing annual base,
    what we expect to retain, what we expect to expand, and what we expect to
    win new. Derive the quota from those and show every input separately, so
    when someone argues with the number they have to argue with a specific
    assumption rather than the total.
    
    Add a coverage multiple: the territory's total potential value divided by
    its quota. Flag anything below a threshold I set. That is a territory
    being asked for a number its account base cannot support, and it is a
    planning error rather than a performance one.
    
    Keep reps separate from territories. A rep is assigned to a territory
    with a start date and a ramp, and the quota belongs to the territory. When
    somebody leaves I want the gap to stay visible on the plan instead of
    disappearing with them.
    
    Roll the quota up by segment, by region and for the whole plan, and let me
    compare the total against the number I have been given.
    
    ## 3. Is this plan even?
    
    Add a view that answers "is my territory fair".
    
    Rank every territory side by side on account count, total potential,
    existing base, quota, coverage multiple, and quota as a multiple of the
    base. For each of those show how spread out the territories are, so I can
    see at a glance which dimension is the unbalanced one.
    
    Include timezone spread and country count too. Account counts hide travel
    and coverage load, and that is the part reps actually feel.
    
    Highlight the three best and three worst territories on each dimension.
    
    I am not trying to make every territory identical. I am trying to know
    exactly where the plan is uneven before a rep tells me in a QBR.
    
    ## 4. Compare two plans
    
    Make plans versioned.
    
    Every plan is a named version with a status: draft, proposed, approved,
    live. Let me clone a version so I can experiment without touching the
    live plan.
    
    Then give me a comparison of any two versions: which territories were
    added or removed, which accounts moved and where they went, and how each
    territory's quota changed.
    
    The screen I care about most is per rep: what they lose, what they gain,
    and what it does to their number. That is the conversation the plan has to
    survive, and I would rather have it with the data in front of me.
    
    Let me export an approved version as a CSV for the CRM load, and record
    which version was exported and when.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read the account universe with the attributes you segment
    on, then export an approved plan back.
    
    <NetSuite>. Read current spend per account, which is what quota is
    actually built from.
    
    <Workday>. Read who is in seat, their start date and ramp, so assignment
    reflects reality.
    
    <a CSV export>. Import the account list to start, before any of the above
    is connected.
    
    <Snowflake>. Read historical performance by account and segment, which is
    what a coverage multiple is checked against.
    
    <Looker>. Feed coverage and balance into the planning dashboard leadership
    already reviews, so the plan is argued from one view.
    
    <Okta>. Resolve reps and managers, so assignment reflects the actual team.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  10. Sales and RevOps

    commission calculator

    Calculate commission from the plan rather than from a spreadsheet nobody can audit, show every rep how their number was reached, and handle the disputes as data. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The plan, versioned properly
    
    In this Helix project, build me a commission calculator.
    
    Start with plans, and get one detail right that causes more disputes than
    anything else. For each tier, I need to say whether the rate applies only
    to the portion of attainment inside that band, or to the whole amount once
    that band is reached. Both models exist in real plans and confusing them
    is the classic commission bug. Make it an explicit choice per tier.
    
    A plan has an effective-from date, a quota period, a base rate, its tiers,
    and any cap. Never edit a published plan version. Editing creates a new
    version, and old periods keep pointing at the version they were calculated
    under.
    
    Then assign reps to plans with a quota, a start date and a ramp. And give
    me a preview: type an attainment figure and show me what it would pay and
    why.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. What counts, before what it pays
    
    Now decide what actually counts.
    
    Load transactions with their booking, close, recognition and cash dates,
    and let the plan say which event and which date qualifies a deal for a
    period. Record on every row which rule qualified it and on what date.
    
    Handle splits: a deal apportioned across several reps by percentage, with
    the total validated to 100.
    
    And handle clawbacks properly. If a qualified deal is later cancelled or
    refunded, create a negative adjustment in the current open period. Do not
    go back and edit the closed period. That period was correct given what was
    known at the time, and it needs to stay that way or nobody can reconcile a
    payment against a statement.
    
    ## 3. Show the working
    
    Now calculate, and treat the working as the output rather than the total.
    
    For each rep and period, store a line per step. Attainment, with ramp
    applied and shown as its own line. Then for each deal: the plan version
    used, the tier the attainment fell in, the rate, the split, the
    calculation performed, and the resulting amount. Then adjustments,
    clawbacks, draws and guarantees, each with a reason and an approver.
    
    The period total is derived from those lines and never entered directly.
    
    Store the derivation as rows rather than computing it on demand. That is
    what lets me answer a question about a period six months after the plan
    changed, which is exactly when it gets asked.
    
    ## 4. Statements, disputes, and closing the period
    
    Give each rep a statement: attainment against quota, every qualifying deal
    with its commission line, adjustments with reasons, and the total.
    Downloadable, and readable without an explanation.
    
    Let them query a specific line rather than emailing about the total. The
    query routes to the plan administrator and the resolution is recorded
    against that line.
    
    Add a review step before payment showing period totals by team, the
    largest payouts, and anything that changed since the last run. Then freeze
    the period on approval. After that, corrections become adjustments in the
    next open period, with a reason, never a silent rewrite.
    
    Finally, an export for payroll, and a record of what was exported and
    when.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read closed deals with their amounts, dates and splits,
    which is what qualifies a transaction.
    
    <NetSuite>. Check invoices and cash received, if your plan pays on
    collection rather than closure.
    
    <Workday>. Read plan assignments and quotas, and export the approved
    period for payment.
    
    <Gmail>. Send each rep their statement, so a dispute happens on a line
    rather than in a thread.
    
    <Snowflake>. Read closed bookings from the warehouse, where the CRM data
    has already been cleaned up.
    
    <Gusto>. Export the approved period to payroll, and record exactly what
    was sent and when.
    
    <Okta>. Authenticate reps and read the manager relationship, which is what
    lets the app show a statement to its owner and their manager and nobody
    else.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  11. Sales and RevOps

    partner referral tracker

    Register referrals, protect them for a defined window, show partners the status of their own deals, and calculate what you owe. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Registration, and the check that decides everything
    
    In this Helix project, build me a partner referral tracker.
    
    A partner submits a deal: their company, the prospect company and domain,
    a contact, the country, the use case, an estimated value and expected
    timing. Timestamp it, because that timestamp is what settles every later
    dispute about who found the deal.
    
    Then the part the whole programme lives or dies on. Check the submission
    against three things: our existing customers, our open opportunities, and
    other partners' active registrations. Match on email domain first and
    company name second, because company names typed into a form almost never
    match what is in our CRM and domains usually do.
    
    Three outcomes. Clean, accept it. An existing customer, reject it with a
    stated reason. A partial match, send it to a person with the matching
    record shown next to it. Never reject silently: a rejected referral needs
    a reason the partner can read.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. What a partner actually gets
    
    On acceptance, set a protection expiry from a window I configure per partner
    tier, say 90 or 180 days.
    
    Let a partner log activity against the referral, and let activity extend
    the window by a set amount up to a maximum, so a partner working the deal
    keeps it and a partner who registered and vanished does not.
    
    Notify the partner and the partner manager at intervals before expiry, and
    again on the day it lapses. A window that expires without warning is worse
    than having no window at all.
    
    When it lapses, move it to a lapsed state that stays visible in history
    rather than deleting it. Those records are how I find out whether the
    window length is right.
    
    ## 3. The partner's own view
    
    Now the partner-facing side, and be careful with it.
    
    A partner signs in and sees only their own referrals: status, protection
    expiry, last update, and a running summary of what they have submitted,
    what was accepted, what closed and what they have earned.
    
    Make the visible fields a configuration rather than a code decision. Some
    programmes share pipeline stage with partners, some share only open, won
    or lost, and I want one app to serve both.
    
    Never expose deal amounts, other partners, or internal notes in that view.
    Everything a partner can see should be something I chose deliberately.
    
    Show the deduplication result at submission, so a partner learns
    immediately rather than a week later.
    
    ## 4. Outcomes and what you owe
    
    Link each referral to an outcome: won with a value and close date, or lost
    with a reason.
    
    Calculate the payout from the partner's tier rate against the value I
    designate as commissionable, which is often not the total contract value.
    Make that an explicit field rather than an assumption.
    
    Then gate eligibility on a condition I set, and default it to invoice
    paid rather than deal closed. Paying on closure eventually means asking
    someone outside the company to give money back, which costs more goodwill
    than the delay costs patience.
    
    A payout run: everything eligible in a period, grouped by partner,
    approved by a named person, exported, marked paid. Plus acceptance rate
    per partner, which is the number that tells me whether a partner
    understands who we sell to.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Check submissions against existing customers, open
    opportunities and other partners' registrations, and link closed outcomes
    back.
    
    <Okta>. Authenticate internal users, kept strictly separate from how
    partners sign in.
    
    <NetSuite>. Confirm an invoice was actually paid before a payout becomes
    eligible.
    
    <Gmail>. Tell a partner their registration was accepted, or rejected with
    a reason they can read.
    
    <HubSpot>. Some partner programmes run on a separate CRM from the direct
    team. Read registrations from there too.
    
    <DocuSign>. Check the partner agreement is signed and current before a
    payout becomes eligible.
    
    <Stripe>. Confirm the invoice was actually collected, if payouts are gated
    on cash rather than closure.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  12. Sales and RevOps

    lightweight CRM

    Contacts, organisations, interactions and a small pipeline, for the teams whose relationships do not belong in the sales CRM. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Organisations and contacts, kept apart
    
    In this Helix project, build me a lightweight CRM for a team whose
    relationships do not belong in the sales CRM.
    
    Two record types, and keep them genuinely separate.
    
    Organisations: name, type, website, region, size band, status, a named
    owner on our side, and a few attributes I will define, because what this
    team segments on is not what sales segments on.
    
    Contacts: name, role, email, phone, and a link to their organisation, as
    a relationship with a start and end date rather than a field. When
    somebody moves to a new company, the history stays with the person and
    the new relationship is added. Losing that history is the most common
    way this kind of app disappoints.
    
    Let one contact be linked to several organisations over time, and show
    the full history on the contact.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The interaction log
    
    Add interactions, and make logging one take under thirty seconds.
    
    Each interaction: date, type (meeting, call, email, event, introduction,
    note), the organisation, which contacts were involved, who from our side,
    a summary, and any follow-up with an owner and a date.
    
    Append-only. Corrections are new entries referencing the earlier one.
    
    Let me paste an email or a set of notes and have you draft the fields for
    me to correct, because the reason interaction logs stay empty is that
    filling them in is tedious.
    
    Show the full history on both the organisation and every contact
    involved, and surface the ones that have gone quiet: organisations with
    no interaction for longer than a threshold I set, ranked by how important
    they are rather than how long it has been.
    
    ## 3. A pipeline with this team's stages
    
    Add a pipeline, and let this team define the stages.
    
    A pipeline record links to an organisation, has a stage, an owner, an
    expected value or outcome, an expected date, and a next step.
    
    Put the stages in a config file and seed them with something generic, but
    make it obvious they are meant to be replaced. A partnerships pipeline is
    not prospecting, qualification, proposal, closed. It is more like
    introduced, exploring, agreed in principle, contracted, live. A recruiting
    pipeline is different again.
    
    Copying the sales pipeline into a partnerships tool produces a pipeline
    nobody updates, because the stages do not describe anything that
    actually happens.
    
    Show it as a board, with anything that has not moved for a set period
    flagged.
    
    ## 4. Draw the boundary, and mean it
    
    Last, and most important: define the boundary with the company CRM.
    
    Add a field on every organisation recording whether it also exists in the
    company CRM, with the link if so, and which system owns the
    relationship.
    
    Then pick a rule and enforce it in the app. Either this system is
    authoritative for its own relationships and never writes to the CRM, or
    it reads the CRM for shared accounts and marks those records read-only
    here. Both are defensible. Having neither is not.
    
    Flag any organisation that exists in both with no owner recorded, because
    that is the row where two teams will eventually contradict each other in
    front of the customer.
    
    Then a handful of reports: interactions per organisation over time, the
    relationships gone quiet, pipeline by stage, and contacts whose email has
    bounced or whose role has changed, which is the maintenance nobody
    does.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read shared accounts so the boundary is real, and mark those
    records read-only here rather than maintaining two truths.
    
    <Okta>. Authenticate every user, because contact records are personal data
    about people outside your company and an anonymous reader is not
    acceptable.
    
    <Gmail>. Log interactions from email without anybody retyping them, which
    is what keeps the history alive.
    
    <Google Calendar>. Pull meetings automatically so a logged interaction is
    the default rather than an act of discipline.
    
    <Slack>. Nudge an owner when an important relationship has gone quiet.
    
    <DocuSign>. Read whether the agreement behind a contracted relationship
    was actually signed.
    
    <Snowflake>. Land the interaction history, so a question like which
    relationships have gone quiet can be asked across years rather than
    months.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  13. Sales and RevOps

    account research app

    Assemble what you already know about an account, add what is public, and keep the result so the next person does not start from nothing. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Assemble what you already hold
    
    In this Helix project, build me an account research app.
    
    Start with what we already know, because that is most of what a rep
    assembles by hand.
    
    For a given account, pull together: contract history and current value,
    open and past pipeline, support tickets and any escalations, product
    usage if we have it, every contact we hold with their role, and the
    history of conversations we have had.
    
    Put it on one page with the age of each piece shown. A support ticket
    from last week and one from two years ago should not look the same.
    
    That page alone removes most of the duplication, because the reason
    everybody researches the same account is that nobody can see what the
    last person found.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Add the external signals that change how you sell
    
    Now add external context, and be selective. The goal is not everything
    findable, it is the handful of facts that change the approach.
    
    Funding and ownership. Headcount trend, and by function if you can get
    it, because a company hiring twenty support agents is telling you
    something. Technologies in use where they are relevant to us. Recent
    announcements, leadership changes and anything in the last quarter that
    suggests a priority.
    
    Cite the source and date of every external claim on the record. A brief
    that cannot say where a number came from cannot be used in front of a
    customer, and somebody will eventually repeat it in a meeting.
    
    Where a signal cannot be verified, mark it as unverified rather than
    leaving it looking like the rest. The difference between a confirmed
    funding round and a rumour matters when a rep quotes it.
    
    ## 3. The point of view, written by a person
    
    Add a written point of view, and make it clear it belongs to a person.
    
    Four short fields: why this account is worth time, what we think they are
    trying to do, who matters and why, and what would make us lose.
    
    Let the app draft each from the assembled context, and require a named
    person to edit and sign it before it counts as research rather than a
    draft. Show the author and the date on the brief.
    
    A generated summary is useful input and a poor substitute for a
    judgement. The value of this field is that somebody will defend it in a
    pipeline review, and nobody defends a paragraph a model wrote.
    
    Keep previous versions, so when the take on an account changes it is
    visible as a change rather than a quiet overwrite.
    
    ## 4. Give it a shelf life
    
    Last, make research expire.
    
    Set a shelf life per section rather than for the whole brief. Contract
    and pipeline data refresh continuously. Headcount and funding age in
    months. A point of view ages fastest of all, because it was written
    against a situation.
    
    Show the age of every section, and mark the whole brief as needing
    refresh once the point of view passes a threshold I set. Do not hide the
    old version, just stop presenting it as current.
    
    Then the reporting worth having: which accounts have research and which
    do not, ranked by pipeline value, so the gap is visible. How often
    research gets refreshed rather than rewritten from scratch, which tells
    you whether people are finding it. And how often a brief is opened by
    somebody other than its author, which is the only real measure of whether
    this removed the duplication it was built for.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read contracts, pipeline, contacts and the history of what
    has been sold to this account.
    
    <Zendesk>. Read open tickets and escalations, which change how a
    conversation should open.
    
    <Amplitude>. Read product usage, so a brief can say whether they are
    actually using what they bought.
    
    <Gong>. Read what has been discussed on past calls, which is the context a
    rep most often lacks.
    
    <Okta>. Verify who is signing in and read their group, which is what the
    app checks before showing a frank internal assessment.
    
    <Snowflake>. Read usage and revenue history at depth, which the source
    systems will not give you cheaply.
    
    <Slack>. Tell the owner when a brief is approaching its expiry rather than
    letting it go quietly stale.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  14. Customer Success

    customer health dashboard

    Build a health score from signals that actually predict renewal, show the trend rather than the number, and turn a red account into a named action. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Signals, kept apart on purpose
    
    In this Helix project, build me a customer health dashboard.
    
    The mistake almost every health score makes is blending everything into
    one number, so usage collapsing gets masked by a quiet support queue. So
    keep five categories separate all the way through the data model: usage,
    adoption, support, relationship and commercial. Blending them is a display
    choice at the end, not a modelling one at the start.
    
    Put the signal definitions in a file I can edit: a key, a category, which
    direction is good, thresholds for good, watch and poor, and a weight.
    
    Seed it with these: weekly active users against licensed users, distinct
    features used, days since anyone logged in, open tickets, escalations in
    the last 90 days, days since we last met them, how many contacts are
    engaged, payment delays, and expansion or contraction last term.
    
    The last two relationship signals are the ones teams leave out, and
    champion departure is the churn cause they most often miss.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Score it, then check whether the score is any good
    
    Score each signal against its thresholds, roll up to a category, then roll
    categories into an overall figure using the weights in that file. Show the
    overall score, but always with the five category scores beside it. A
    category in the poor band has to stay visible even when the total looks
    healthy.
    
    Snapshot every score daily, so trend is history rather than a
    recalculation.
    
    Then build the back-test, and build it now rather than later. Let me load
    a list of accounts that churned or contracted with their dates, and report
    what the score and each category said 30, 60 and 90 days beforehand. Show
    me which individual signals had predictive value and which were noise.
    
    Without that, a health score is a shared opinion with a colour attached.
    
    ## 3. The screen a CSM opens on Monday
    
    Build the portfolio view for whoever is signed in: their accounts, sorted
    by risk, showing score, direction over 30 days, renewal date, contract
    value, and which category is currently weakest.
    
    Rank by contract value at risk rather than score alone. A small account at
    20 outranking a large one at 55 and falling gets the priorities exactly
    backwards.
    
    Then the account view: the overall score charted over time, each category
    charted, and the individual signals behind whichever category is weakest.
    Let me annotate the chart with events I record, like an escalation or a
    champion leaving.
    
    And flag any account that dropped more than a threshold I set in the last
    30 days, regardless of where it started.
    
    ## 4. Turn a red account into something someone does
    
    When an account crosses into a risk band or drops sharply, create a draft
    intervention assigned to its owner, pre-filled with the category that
    moved and the signals behind it. Alert the owner and their manager with
    the reason in the message, not just the score.
    
    Track what happened to each intervention: what was done, by when, and the
    outcome.
    
    Then report whether accounts that received an intervention recovered more
    often than those that did not. That is uncomfortable and it is the only
    honest measure of whether this dashboard is worth running.
    
    Finally a renewal view: accounts renewing in the next two quarters, ranked
    by score and value. That list is where a renewal forecast should start.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Amplitude>. Read active users, feature breadth and last login, which is
    the usage half of the score.
    
    <Zendesk>. Read ticket volume and escalations, which is the signal teams
    already have and rarely weight.
    
    <Salesforce>. Read contract value, renewal dates and who the engaged
    contacts are.
    
    <Google Calendar>. Read days since the last meeting, which is the
    relationship signal most scores omit.
    
    <Okta>. Verify identity and read the manager chain, which is what the app
    uses to give an owner their accounts and leadership the whole book.
    
    <Snowflake>. Read the history behind each signal, which is what makes the
    back-test possible.
    
    <Looker>. Publish the book view for the leadership review without a second
    export.
    
    <Slack>. Alert an owner when an account drops sharply, with the category
    that moved in the message.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  15. Customer Success

    QBR prep tool

    Assemble the usage, support, commercial and relationship picture for an account into one reviewable draft, so preparation is editing rather than gathering. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The template, and why it is fixed
    
    In this Helix project, build me a QBR prep tool.
    
    Start with the template, and keep it in one config file. An ordered list of
    sections, each with a title, a purpose line, and the metric keys it needs.
    Seed it with: executive summary, adoption and usage, value delivered,
    support experience, commercial position, risks, and next quarter's plan.
    
    Creating a review instantiates that template for one account and one
    period. Keeping it in config means changing the QBR format changes every
    future review without anyone touching an account.
    
    Then the account data it hangs off: name, segment, contract value,
    contract dates, renewal date, the success owner, the account executive,
    and the key contacts with their roles.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Fill it in, with context rather than raw numbers
    
    Now assemble the metrics.
    
    For every metric in a review, show the current period, the previous
    period, the same period last year, the absolute and percentage change, and
    the direction. Never a bare number. A usage figure with nothing beside it
    is a slide that gets nodded at.
    
    Flag anything that moved more than a threshold I set per metric, and open
    each section with what changed rather than with a full table. A review
    that covers twenty metrics equally covers none of them.
    
    Import from CSV per source to start, with the mapping in one editable
    file, structured so I can swap in a live connection later.
    
    One thing to get right: handle missing data honestly. A metric with no
    value says so. Do not render it as zero. A zero on a customer-facing slide
    starts an argument you cannot win.
    
    ## 3. The part that stays human
    
    Each section gets the generated data plus a place to write the narrative.
    
    Pre-fill each narrative with last quarter's text for that account, marked
    clearly as carried over, so the author is editing rather than facing a
    blank box. Most sections change by a sentence.
    
    Add a risks section where each risk has an owner, a severity and a
    mitigation, and carries forward until it is closed. And an asks section:
    what we want from the customer this quarter, and what they have asked of
    us.
    
    Give the review a state: draft, internal review, ready, delivered. Let a
    manager comment on a draft without editing it.
    
    Export the finished review as a document, and keep that export next to the
    record. The underlying numbers get corrected and backfilled, and six
    months later the question is what we actually presented, which sometimes
    has legal weight.
    
    ## 4. Make the meeting compound
    
    Last, and most important: track commitments.
    
    Capture what each side agreed to, with a named owner on our side or
    theirs, a due date, a status and an outcome. Capture them during or
    straight after the review.
    
    Then have the next review for that account open with an automatic section
    listing every commitment from last time and where it stands. Nothing else
    in this tool changes behaviour as much as that one screen.
    
    Remind owners of overdue commitments before the next scheduled review, so
    the status is real rather than updated in the meeting. And report
    completion rate by owner across accounts, plus the accounts carrying the
    most overdue items, which tends to correlate with the accounts in
    trouble.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Amplitude>. Pull the adoption metrics the review covers, with the
    previous period beside them.
    
    <Salesforce>. Read contract value, renewal date, contacts and open
    opportunities for the account.
    
    <Zendesk>. Pull the ticket count and any escalation for the period, which
    is the section customers always ask about.
    
    <Google Drive>. Keep the exported review, so what you presented survives
    the numbers being corrected later.
    
    <Okta>. Confirm the reader is a member of staff, because the draft carries
    risks and internal narrative that never go in front of the customer.
    
    <Google Slides>. Push the assembled review into the deck template the team
    already presents from.
    
    <Snowflake>. Read the metric history so every figure has last quarter
    beside it.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  16. Customer Success

    customer escalation tracker

    Give escalations a severity, an owner, a communication cadence and a closure record, so the customer hears from you on schedule rather than when someone remembers. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Severity that means something
    
    In this Helix project, build me a customer escalation tracker.
    
    Start with severity, because it drives everything else. Put the levels in
    a config file, and for each one define the customer impact that qualifies,
    the first response time, how often the customer must hear from us, who is
    notified when it is raised, and who is notified if it stays open too long.
    
    Define severity by customer impact, never by how hard the problem is
    internally. Those point in opposite directions more often than people
    expect. Show the qualifying description to whoever is raising it, so they
    can assess it themselves, which stops severity inflation without needing a
    triage meeting.
    
    Then the escalation itself: account, customer contact, who raised it,
    description, severity, a single named owner, the technical lead, status,
    and target and actual resolution dates.
    
    Require the owner. Do not let one be created or reassigned without a named
    person. Their job is the relationship and the communication, and it cannot
    be shared.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The timeline, and what was promised
    
    Add a timeline, and make it append-only. Corrections are new entries
    referencing the earlier one, never edits. An escalation timeline that can
    be edited is worth nothing when it matters.
    
    Each entry has a type: internal note, customer communication, status
    change, or commitment. Status and severity changes write their own entry
    automatically, with the before and after.
    
    Then keep commitments in their own table, separate from the timeline. What
    was promised, to whom, by when, owner, status. A promised date buried in a
    note is a promise nothing is tracking, and the customer will remember it
    even if we do not.
    
    ## 3. The countdown that actually matters
    
    Now the part that changes outcomes.
    
    Calculate when the next customer update is due from the severity and the
    timestamp of the last customer communication. Not the last internal note.
    Internal activity is not communication, and teams feel extremely busy on
    an escalation while the customer hears nothing for four days.
    
    Show that countdown on every escalation and sort the list by it, so the
    most overdue update is the first thing anyone sees. Notify the owner
    before it falls due and their manager once it is late.
    
    Then build an update composer that pre-fills a draft with what has changed
    since the last customer communication: status changes, commitments made or
    met, and any timeline entries marked customer-relevant. The owner edits and
    sends, and sending logs a customer communication.
    
    And a daily digest to leadership: open escalations by severity, anything
    overdue, anything raised in the last day.
    
    ## 4. Closing it properly
    
    Closure requires four things: a resolution description, a root cause from a
    short editable list, confirmation that the customer agrees it is resolved,
    and a follow-up check-in date. Create the follow-up automatically and
    notify the owner on the day. An escalation closed without one reopens as a
    surprise.
    
    Then report: escalations by account, root cause, severity and month. Time
    to first response and to resolution against the targets in the severity
    config. Repeat accounts and repeat root causes, which are the two lists
    worth taking into a product or operations review.
    
    And correlate open and recent escalations with renewal dates. An account
    escalating three months before renewal is a commercial risk, not just a
    support one, and nobody looks at those two facts together.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Link the escalation to the account and its renewal date,
    which is what makes it a commercial risk and not just a support one.
    
    <Zendesk>. Pull the tickets behind the escalation so the timeline starts
    from a record.
    
    <Gmail>. Send the customer update, and log the send as a communication
    that resets the clock.
    
    <Slack>. Reach the owner before an update falls due, and their manager
    once it is late.
    
    <Okta>. Read the group that separates the account team from everyone else,
    since the internal timeline is written far more bluntly than anything the
    customer sees.
    
    <PagerDuty>. Wake somebody for a severity one raised out of hours, which
    email will not.
    
    <Jira>. Link the escalation to the engineering work behind it and read
    status back.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  17. Customer Success

    renewal tracker

    Work renewals from the notice date backwards, with a stage for each step, an owner, and a forecast leadership can trust. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Work backwards from the date that actually decides it
    
    In this Helix project, build me a renewal tracker.
    
    Load contracts: account, product, annual value, currency, term start and
    end, whether it auto-renews, the notice period in days, any contractual
    uplift, payment terms, and an owner.
    
    Now derive two dates and treat both as more important than the contract
    end. The notice deadline, which is term end minus notice period. And the
    engagement date, which is the notice deadline minus a lead time I
    configure per contract value band. A large enterprise renewal needs to
    open six months out and a small one needs six weeks, and one global
    setting serves neither.
    
    Then show me the next twelve months ordered by engagement date, with days
    remaining, value, owner and stage. And put anything already past its
    engagement date and not started at the very top. That list is the entire
    reason for building this.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Stages with entry criteria
    
    Add stages, in a config file: an ordered list with entry criteria and an
    expected duration. Start with not started, discovery, value review,
    proposal, negotiation, closed won, closed lost, and let me edit them.
    
    Show the entry criteria when somebody moves a renewal into a stage, and
    record who moved it and when. Without criteria, everything piles up in the
    middle stage until the month it closes and the pipeline tells you nothing
    you did not already know.
    
    Give each renewal a plan: the customer decision-maker and their role, the
    known risks, the value evidence to present, and the next step with a date
    and an owner.
    
    Flag any renewal that has been in a stage longer than its expected
    duration.
    
    ## 3. A forecast someone can interrogate
    
    Now the forecast, and do one thing differently from every CRM.
    
    Categories are committed, likely, at risk and lost. Whenever a renewal is
    set to at risk or lost, require a reason chosen from a short editable
    list. Not a probability. Nobody can argue with 60 percent, and everybody
    can argue with "champion left and the replacement has not engaged", which
    is the conversation you actually want.
    
    Roll up by quarter: base renewal value, expansion, contraction, and the
    net. Derive gross renewal rate and net revenue retention from those rather
    than letting anyone type them. A contract renewed at 60 percent of its
    size is not a win, and a tracker that only asks whether it renewed will
    record it as one.
    
    Show the forecast three ways, committed only, committed plus likely, and
    full pipeline, so a leadership conversation can happen without anyone
    arguing about which number is meant. Snapshot it weekly and chart how each
    quarter's number moved. The shape of that line teaches a team more about
    its own optimism than any coaching.
    
    ## 4. Connect it to what the account is doing
    
    If I connect them, pull per-account signals onto the renewal record: usage
    trend, open escalations, ticket volume, health score, days since the last
    meeting.
    
    Then build the single most useful alert in the app: any renewal where a
    signal is deteriorating and the forecast category is still committed.
    That contradiction is what a renewal tracker can see and a health
    dashboard on its own cannot.
    
    On closure, record the outcome, the final value, a reason from a fixed
    list, and free text. Then report renewal rate by segment, owner and
    contract size, loss reasons over time, and how accurate each forecast
    category turned out to be once quarters closed. Flag any lost renewal
    above a value threshold for a post-loss review with an owner and a due
    date.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read renewal opportunities and write the forecast category
    and decision back.
    
    <Stripe>. Read subscription term dates, billing schedule and value, which
    is where the engagement date comes from.
    
    <Amplitude>. Pull the usage trend, so a committed forecast on a declining
    account shows as the contradiction it is.
    
    <Google Calendar>. Put the engagement date in the owner's calendar, so
    preparing for the conversation is scheduled rather than remembered.
    
    <Okta>. Resolve owners and their manager chain, which is what the app uses
    to show a rep their renewals and leadership the roll-up.
    
    <Zendesk>. Read open escalations, so a committed forecast on an unhappy
    account shows as the contradiction it is.
    
    <Snowflake>. Read the usage and payment history behind each renewal, which
    is the evidence for the conversation.
    
    <Slack>. Warn the owner at the engagement date, which is months before the
    renewal date.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  18. Customer Success

    B2B customer portal

    Let customers see their own account, users, usage and documents, with the multi-tenant boundary and the organisation model built in from the first commit. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The tenant boundary, before any feature
    
    In this Helix project, build me a B2B customer portal. Before any feature,
    get the tenant model right, because this is the part that cannot be added
    later without auditing everything.
    
    Organisations are first-class records: name, status, plan, account
    manager, created date, and a reference to our CRM or billing record.
    
    Users have no organisation column. Instead there is a membership record
    linking a user to an organisation with a role, a status, who invited them
    and when. A user can belong to more than one organisation. Partners,
    contractors and customers who acquire each other all produce that case.
    
    Add an active organisation in the session, with a switcher for people who
    belong to several.
    
    Then build one data access layer that every query goes through. It
    requires an organisation id and denies by default: a query with no explicit
    scope returns nothing, not everything.
    
    Now write tests for that boundary before writing a single feature. For
    every table, assert that a user in organisation A cannot read, update or
    delete a record belonging to organisation B, whether by id, by search, or
    through any list endpoint.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Build for the emails your team actually gets
    
    Now the customer-facing features, in this order, because it is roughly the
    order your team currently answers them by hand.
    
    Account overview: plan, contract dates, renewal date, primary contact, and
    the account manager with a way to reach them.
    
    Billing: invoices with status and amount, downloadable, plus payment
    history. This is the single most requested item in most portals.
    
    Usage against entitlement: what they have used this period against what
    they are entitled to, with history. Put the definition of the metric next
    to it. A usage number people do not understand generates more enquiries
    than it prevents.
    
    Users: everyone at their organisation with access, their role, and their
    last sign-in.
    
    Documents: contracts, order forms, security documentation, anything we
    currently email on request.
    
    Requests: any open support ticket or service request with its status.
    
    For each of these, if we do not have a reliable source for the data, say
    so rather than showing an approximation. A wrong invoice figure costs more
    trust than a missing feature.
    
    ## 3. Let the customer do the work you are doing for them
    
    Define roles within an organisation in a config file: at minimum
    administrator, member and billing contact, each with a description of what
    it can see and do.
    
    An administrator at the customer can invite users by email, set and change
    roles, deactivate people, and see pending invitations. Taking the account
    manager out of that loop removes a large share of the inbound this portal
    exists to reduce.
    
    Invitations expire, and re-inviting issues a new one rather than extending
    the old.
    
    Give their administrator an organisation-level audit: who signed in, who
    was invited or removed, who changed a role, who downloaded which document.
    
    Support optional domain-based joining, off by default, where anyone with
    an email at a verified domain can request access and an administrator
    approves. Verify the domain properly and never enable it for a free-mail
    domain.
    
    And give users notification preferences, because a portal that emails too
    much gets filtered and then nobody sees the important one.
    
    ## 4. Helping a customer without breaking the boundary
    
    Add a staff role that exists outside the organisation model and is
    authenticated separately from customer users.
    
    Never grant a staff member a membership in a customer organisation to give
    them access. It works immediately, and it destroys the meaning of both the
    boundary and the audit log.
    
    Instead build view-as for support: strictly read-only, time limited,
    clearly indicated in the interface throughout, and audited on entry and
    exit with the reason recorded.
    
    Give staff a view of any organisation showing the same data the customer
    sees, so a support call is about the same screen.
    
    Add health signals for the account team: last sign-in by anyone at the
    organisation, active users against licensed, and features never used. An
    organisation where nobody has signed in for sixty days is worth knowing
    about before the renewal.
    
    And rate limit every customer-facing endpoint. This is an internet-facing
    app holding one customer's data next to another's.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Stripe>. Read invoices, payment history and plan, which is the single
    most requested thing in any portal.
    
    <Okta>. Authenticate customer users and staff separately, and support a
    customer bringing their own.
    
    <Amplitude>. Show usage against entitlement, with the metric definition
    beside it.
    
    <Zendesk>. Show the status of their open requests, so they stop emailing
    to ask.
    
    <Salesforce>. Read the account, contract dates and account manager, so the
    portal shows the same thing your team sees.
    
    <Google Drive>. Serve contracts, order forms and security documentation
    that you currently email on request.
    
    <Snowflake>. Read the usage totals behind the entitlement view, aggregated
    once a day rather than counted live on every page load.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  19. Customer Success

    support performance dashboard

    Volume, resolution and satisfaction in one view, split by what customers actually contacted you about, with NPS or CSAT joined to the ticket that caused it. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Volume, by what people actually wanted
    
    In this Helix project, build me a support performance dashboard.
    
    Pull tickets with their customer, channel, product area, priority, dates
    opened, first responded and resolved, the assignee, and the outcome.
    
    Then the part that matters: a contact reason on every ticket, from a
    taxonomy I can edit. Seed it with categories like how-do-I, broken,
    billing question, access problem, data question, feature request, and
    bug already known.
    
    Report volume by reason first and by channel second. Channel tells me how
    busy support is. Reason tells the rest of the company what to fix, and it
    is the only version of this report that causes anything to change
    outside the support team.
    
    Where reason is missing, say so rather than bucketing into other. The
    proportion of tickets with no reason is itself the first thing to fix.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Two clocks, and the worst decile
    
    Measure resolution as two separate numbers.
    
    Time to first response, and time to full resolution. Report them apart.
    Slow first response is a staffing or routing problem. Slow resolution is
    a complexity or escalation problem. A single time-to-close figure hides
    which one you have, and the two fixes are unrelated.
    
    Show the median and the ninetieth percentile side by side for both. The
    median is what a team reports; the ninetieth percentile is who is
    actually furious, and the gap between them is the story.
    
    Exclude time spent waiting on the customer from resolution, but track it
    separately and show it. A large share of what looks like slow support is
    a ticket sitting with the person who raised it.
    
    Break both down by reason, so the categories that are slow to resolve are
    visible rather than averaged into the ones that are quick.
    
    ## 3. Join satisfaction to the ticket
    
    Add satisfaction, and attach it to the ticket rather than the period.
    
    Import CSAT responses per ticket and NPS responses per contact, with the
    free-text comment kept verbatim.
    
    Then join them: for every low score, show the ticket that produced it,
    its reason, how long it took, who handled it and what the customer wrote.
    An aggregate score with nothing behind it is a mood. A low score with the
    ticket attached is a finding somebody can act on.
    
    Report satisfaction by reason, by agent and by resolution time, so you
    can see whether slow tickets or particular categories drive the low
    scores. Those are usually different answers.
    
    And show response rate. A satisfaction score built on eight percent of
    tickets is a different fact from one built on sixty, and dashboards
    routinely present them identically.
    
    ## 4. Repeat contacts, and what to send upstream
    
    Last, build the repeat contact view.
    
    Find customers who contacted you more than once about the same reason
    within a window I set, and customers who reopened a resolved ticket.
    Report the rate, and rank reasons by how often they generate a repeat.
    
    Repeat contacts are the strongest quality signal support has. A category
    resolved quickly and generating repeats was not actually resolved, and
    that is invisible in every other number on this page.
    
    Then produce the report that leaves the support team: the top contact
    reasons by volume, by repeat rate and by dissatisfaction, ranked. That is
    the list to take to product and engineering, and it is the reason to
    build this rather than accept the ticket tool's own reporting.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Zendesk>. Read every ticket with its dates, assignee, channel and
    outcome. The primary input.
    
    <Okta>. Read the manager relationship, which is what the app checks before
    showing one agent's performance to another.
    
    <Salesforce>. Join tickets to the account and its contract value, so
    volume can be read against who is generating it.
    
    <Snowflake>. Read ticket history at volume, which the support tool will
    not give you cheaply for trend analysis.
    
    <Jira>. Raise the engineering work that would remove a recurring reason,
    and read status back so the dashboard shows what is being fixed.
    
    <Amplitude>. Check whether the customers contacting you about a feature
    are actually using it.
    
    <Slack>. Send the weekly top-reasons digest to product, which is the point
    of the whole dashboard.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  20. Customer Success

    customer onboarding tracker

    Track every new customer through the same stages, with the tasks that belong to them as visible as the ones that belong to you. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A plan built from what they bought
    
    In this Helix project, build me a customer onboarding tracker.
    
    An onboarding record per customer: account, close date, contract value,
    products bought, our owner, their project lead, target live date, current
    stage, and status.
    
    Then task templates with conditions, so the plan assembles itself. Each
    template has a description, an owner side (us, them, or joint), a stage,
    a day offset from kickoff, whether it blocks progress, and the conditions
    under which it applies.
    
    Conditions run over what the customer actually bought: which products,
    whether they need data migration, whether a security review is required,
    how many users, which integrations, whether they are regulated.
    
    A customer buying one product with no migration should get eight tasks. A
    complex enterprise rollout should get forty. Giving both the same
    checklist means the first is annoyed and the second is under-served.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Show what you are waiting on them for
    
    Now split tasks by who owns them, and make the customer-owned ones as
    prominent as your own.
    
    Three owner types: us, them, joint. Every task has one, plus a named
    person on that side.
    
    Show a per-customer view with three columns, and count them separately.
    "Nine tasks outstanding, seven of them theirs" is a completely different
    conversation from nine outstanding tasks.
    
    Track how long each task has been waiting, and report waiting-on-customer
    time separately from our own. Most onboarding delay is a customer who has
    not sent the data, granted the access or made the decision, and a tracker
    that reports only our tasks says green while nothing moves.
    
    Give the customer their own view if you want them to have one, showing
    only their tasks and the overall progress. Nothing internal.
    
    ## 3. Define live before you start
    
    Add a written definition of live, agreed at kickoff and shown on the
    record.
    
    It should be specific and checkable: which integrations are connected,
    how many users are active, which workflows are running in production,
    what the customer has confirmed. Not "the customer is happy".
    
    Then add stages between kickoff and live, with entry criteria: kickoff,
    configuration, data migration, integration, training, pilot, live. Let me
    edit that list, and show the criteria when somebody moves a customer
    forward.
    
    Flag any onboarding with no definition of live recorded. Those are the
    ones that run for six months, and the absence of that field is the
    earliest warning you get.
    
    ## 4. Measure from the close date
    
    Last, the measurement, and start the clock earlier than feels natural.
    
    Track four intervals: close to kickoff, kickoff to first value, first
    value to live, and total close to live. Report them separately.
    
    Close to kickoff is usually the largest and is owned by nobody, because
    sales think they have handed over and delivery think it has not started.
    Measuring it is the whole reason to start the clock at close.
    
    Surface stalled onboardings ranked by contract value and days stalled,
    and show them to the account team as well as the delivery team. A
    customer stuck in configuration for five weeks is a renewal risk before
    it is a delivery problem, and the account owner usually finds out last.
    
    Then report time to live by product and by segment, the tasks that most
    often block, and the proportion of delay that was ours versus theirs.
    That last number will be uncomfortable and it is the one worth having.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read the closed deal, what they bought and the contract
    value, and write onboarding status back so the account team can see it.
    
    <Okta>. Authenticate internal staff, kept separate from however customers
    sign in, so the app can tell the two apart before deciding what to show.
    
    <Slack>. Chase the owner of a blocking task, and tell the account team
    when an onboarding stalls.
    
    <Gmail>. Send the customer their outstanding tasks, which is most of what
    an onboarding manager does by hand.
    
    <Amplitude>. Read whether the customer has actually started using the
    product, which is the honest test of first value.
    
    <Zendesk>. Show tickets raised during onboarding, since a customer
    struggling usually appears here first.
    
    <Google Drive>. Hold the migration files and configuration documents
    alongside the plan rather than in an email thread.
    
    <Snowflake>. Push onboarding history into the warehouse so time to value
    by product and segment is a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  21. People

    headcount request tracker

    One record per role from request to filled, with approval, budget, and a status that finance, recruiting and the hiring manager all read the same way. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A request finance can actually act on
    
    In this Helix project, build me a headcount request tracker.
    
    A manager asks for a role, so capture: title, level, team, cost centre,
    location, employment type, salary range, the business case, and the
    priority. Require them to say whether it is a new role or a backfill at
    the moment they create it, and treat those differently everywhere. They
    have different approval paths and different budget consequences.
    
    Now the field almost every tracker misses. Ask for the month the budget
    funds the role from, not a target start date, and derive the in-year cost
    from it. A role starting in month ten costs a quarter of one starting in
    month one, and approving a role is not the same as approving twelve months
    of salary.
    
    Let me load the headcount plan, link each request to a plan line where one
    exists, and flag requests that match nothing. Off-plan hiring is not wrong.
    It just has to be visible.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Get finance in before the offer, not after
    
    Route approvals through rules I can edit: based on level, cost centre and
    annualised cost, producing an ordered list of required approvers. Always
    include finance above a threshold I set. Finance approving after an offer
    is out is the failure this whole app exists to prevent.
    
    Give every approver a deputy with automatic reroute after a set number of
    days, and show the requester exactly where their request is sitting and
    with whom.
    
    Record every decision with the approver, timestamp, reason, and a snapshot
    of the request at that moment. Then do the unpopular but necessary thing:
    if anyone edits the salary range, level or start month after approval,
    reset the affected approval steps. Without that, roles get approved at one
    level and recruited at another, and nobody notices until the offer.
    
    ## 3. One record, two views
    
    Use a single status list for the whole life of a role: requested, approved,
    open, in process, offer out, offer accepted, filled, on hold, withdrawn,
    cancelled. Do not create a parallel recruiting status. Two lists kept in
    sync is the problem, not the solution.
    
    Record every transition with a timestamp and who made it. Put the
    recruiting fields on the same record: recruiter, posting link, candidate
    count, current stage, offer details, accepted date, actual start date.
    
    Then build two views over that one dataset. Recruiting sorts by stage and
    age. Finance sorts by cost impact and funded start month.
    
    And derive the timings separately: request to approval, approval to open,
    open to offer, offer to accepted, accepted to start. Reporting those apart
    changes the conversation in a hiring review more than any other number
    here, because most of what gets called slow recruiting happened before the
    role was opened.
    
    ## 4. Answer how many people we are hiring
    
    Report plan versus approved versus filled, by team and quarter, with the
    gap shown in both roles and money.
    
    Project the monthly cost impact from funded start months, so finance can
    see the in-year and annualised effect of everything currently approved.
    List off-plan approvals separately with their approvers and reasons.
    
    Age the pipeline: approved roles not yet open, and open roles past a
    threshold, each with an owner.
    
    Add a hiring freeze mode that puts every non-exempt request on hold with a
    reason and notifies the requesters. You will need it one day and you will
    not want to build it that morning.
    
    And let me export a snapshot for a board pack, and keep it, so a later
    correction does not change a number that has already been reported.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Workday>. Read the current org, managers and levels, and write filled
    roles back when somebody starts.
    
    <NetSuite>. Read the headcount plan and cost centres, which is what makes
    a request more than a wish.
    
    <Greenhouse>. Pull recruiter, stage and offer status onto the same record,
    rather than a parallel list.
    
    <Slack>. Chase approvers and tell requesters where their role sits.
    
    <Okta>. Read the group that says who is in finance or HR, which is what
    the app checks before showing a salary range. These are the most sensitive
    fields in the library.
    
    <Gusto>. Read actual payroll cost per role, so the in-year projection is
    real rather than a band.
    
    <Google Sheets>. Take the approved plan in the form finance built it, so
    the tracker agrees with the file the CFO signed off.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  22. People

    interview scorecard app

    Score candidates against the competencies the role actually needs, collect evidence rather than impressions, and make the hiring decision from a comparable record. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Decide what good looks like, in words
    
    In this Helix project, build me an interview scorecard app.
    
    Start with competencies, and do not ship a numeric scale without written
    anchors. For each competency, write out what a 1, a 3 and a 5 actually
    look like behaviourally. A scale of one to five with no words attached
    produces ratings that are not comparable between two interviewers, which
    makes the whole exercise decorative.
    
    Then roles: title, level, family, hiring manager. Attach a set of
    competencies to each role with a weight, and let me clone a role's set as
    the starting point for another role in the same family.
    
    And a question bank: per competency, questions worth asking and what a
    good answer contains.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Assign coverage deliberately
    
    Add candidates, panels and assignment.
    
    For each interview, assign that interviewer specific competencies rather
    than letting everyone assess everything. Then check the panel: warn me if
    any competency for this role is assigned to nobody, and warn me if one is
    assigned to more than two people.
    
    Four people assessing the same broad trait while nobody assesses the
    specific skill is the standard way a panel fails, and it is invisible
    unless something checks for it.
    
    On the page where each interviewer writes their feedback, give them their
    assigned competencies, the behavioural anchors, and suggested questions
    from the bank. Nobody should have to go and find those.
    
    ## 3. Independent scoring
    
    Now scoring, and this is the most important rule in the app.
    
    Hide every other interviewer's score and comments until the signed-in
    interviewer has submitted their own. Interviewers who can see an earlier
    strong yes produce more strong yeses, and the panel then reads its own
    convergence as evidence, which is exactly backwards.
    
    Require written evidence on every rating. A score with no example is an
    impression, and impressions are where bias lives. Do not accept a rating
    without one.
    
    Give each interviewer an overall recommendation from a fixed list: strong
    no, no, yes, strong yes. No neutral option. A panel of maybes decides
    nothing.
    
    Lock a submission once made. An edit creates a visible revision with a
    reason, rather than quietly replacing the original. And chase unsubmitted
    feedback automatically, with the debrief as the deadline.
    
    ## 4. The debrief, and what it tells you about your interviewers
    
    Build the candidate summary: every competency, each interviewer's rating and
    evidence side by side, and the weighted total. Show the spread as well as
    the average, and highlight any competency where interviewers disagreed by
    more than a threshold. Disagreement is information and averaging destroys
    it.
    
    Add a comparison view for several candidates on the same role, on the same
    competencies, with evidence expandable inline. Then a decision record:
    outcome, who decided, when, why, and which competencies drove it.
    
    Finally, three reports. Score distribution per interviewer, so I can see
    who rates everyone highly and who has never given a strong no.
    Competencies that never discriminate between candidates, which are
    measuring nothing and should be dropped. And time from interview to
    feedback submitted.
    
    Add a retention rule too: flag candidate data older than a period I set
    for deletion, and show me what is due.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Greenhouse>. Read candidates, roles and scheduled interviews, and write
    the decision back once the debrief closes.
    
    <Okta>. Resolve interviewers to real accounts, so the app can match a
    person to the panels they are actually on.
    
    <Google Calendar>. Read who is on which interview, so assignment does not
    need re-entering.
    
    <Gmail>. Send the scorecard link and the reminder by email, for the panel
    members who do not live in chat.
    
    <Zoom>. Read which interviews actually happened, so chasing feedback is
    not based on the calendar invite.
    
    <Slack>. Chase unsubmitted feedback before the debrief, which is most of
    what this saves.
    
    <Snowflake>. Push scores into the warehouse for the calibration reporting,
    without holding candidate data twice.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  23. People

    onboarding and offboarding tracker

    Generate the right task list per role, route each task to the team that owns it, and prove that access was actually removed. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Lists that write themselves
    
    In this Helix project, build me an onboarding and offboarding tracker.
    
    Start with templates rather than a checklist. Each task template has a
    description, an owning team, a day offset relative to the start or leave
    date, whether it blocks other tasks, whether it requires evidence, and
    conditions saying when it applies.
    
    Those conditions run over person attributes: department, role family,
    level, location, employment type, and the systems the role needs. Adding a
    person generates their task list by evaluating every template. Show me
    which templates matched and which did not, so I can see why a list looks
    the way it does.
    
    Do not build one generic checklist. Every new starter would get irrelevant
    tasks and miss real ones, and after two months people stop trusting it.
    
    Make every due date an offset from the start or leave date, never a fixed
    date. Start dates move constantly, and the whole plan should move with
    them.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Tasks go straight to whoever does them
    
    Each task lands directly in the owning team's queue. No coordinator in the
    middle forwarding requests, because that step is where the four days a new
    starter waits for a laptop actually go.
    
    Give each team a view of what is due today, what is overdue, and what is
    coming in the next week, with the person and their start or leave date on
    every row.
    
    Support dependencies: a task can require another first. Show a blocked
    task as blocked and on what, and notify the owner of the blocking task
    rather than the blocked one.
    
    Give the manager and the new starter their own view of progress, without
    exposing tasks that are not theirs.
    
    Escalate overdue tasks to the owning team's manager after a set period,
    and escalate anything overdue on a leave date immediately.
    
    ## 3. Offboarding, which is the half with real risk
    
    Now build offboarding properly, because a missed onboarding task is a bad
    first week and a missed offboarding task is standing access for somebody
    who has left.
    
    Two modes: planned, where the leave date is known, and immediate, where
    access goes today. Immediate skips scheduling and puts everything in the
    queue now.
    
    Keep an access inventory per person: every system they have access to, the
    level, and the owning team. Populate it from the provisioning tasks during
    onboarding, so the offboarding list is generated from what was actually
    granted rather than from a standard list written two years ago.
    
    Access removal tasks require evidence: which account was disabled or
    deleted, when, and by whom. A tick box confirms somebody clicked
    something. An access review asks what was actually removed.
    
    And cover the tasks people forget: mailbox delegation, calendar handover,
    document ownership, on-call rota removal, physical items returned.
    
    ## 4. Keep it accurate, and make the audit one click
    
    Report time to complete per task type, so I can see which step is the
    bottleneck. It is usually one team and one task. Then completion rate by
    team and month, and average days to full access removal after a leave
    date.
    
    Show me tasks routinely skipped or marked not applicable. That is a
    template whose conditions need fixing, not a compliance problem.
    
    Build the audit view: every person offboarded in a period with their
    access removal evidence, exportable. This gets asked for and it should
    take one click.
    
    And version the templates, so changing one does not alter the task lists
    of people already mid-onboarding. That is the most confusing bug this kind
    of app can have.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Workday>. Read joiners, leavers and role changes, which is what generates
    a task list without anybody remembering.
    
    <Okta>. Create accounts on the way in, disable them on the way out, and
    record the evidence that it happened.
    
    <Jamf>. Assign and reclaim hardware, and confirm the laptop actually came
    back.
    
    <Slack>. Land each task in the owning team's queue rather than a
    coordinator's inbox.
    
    <Google Workspace admin>. Create and suspend accounts, set mailbox
    delegation, and transfer document ownership on the way out.
    
    <Gusto>. Read the payroll start and leave dates, which are sometimes the
    only accurate ones.
    
    <Jira>. Raise the provisioning tasks in the queue IT already works from.
    
    <Zendesk>. Close or reassign anything the leaver still owns before their
    access goes.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  24. People

    leave and cover tracker

    Track who is away, but also who covers which responsibility, so leave approval considers coverage rather than just a balance. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Leave, done correctly
    
    In this Helix project, build me a leave and cover tracker.
    
    Start with the ordinary half. Leave types in a config file: whether each
    deducts from a balance, whether it needs approval, notice required,
    maximum consecutive days, and any documentation requirement.
    
    Requests with start and end dates, half-days at either end, and the
    working days calculated. Calculate those against that person's own
    location calendar and working pattern, not a generic one. Public holidays
    vary by country and quietly break every naive implementation of this.
    
    Show five numbers on a balance, not one: entitlement, accrued to date,
    taken, booked but not yet taken, and remaining. "Remaining" on its own
    hides the three weeks somebody has already booked in December.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Write down what only exists in people's heads
    
    Now the part no leave tool does.
    
    Build a list of responsibilities: things that must always have somebody
    available to do them. For each one, a description, a criticality, and the
    minimum number of available holders required at any time. Then record who
    holds each, and at what level: primary, secondary, or trained.
    
    Seed it with the real ones: payment approval above a threshold, incident
    commander, production deploy approval, contract signature, the escalation
    owner for a named account, payroll submission.
    
    Then two reports that need no leave data at all. Any responsibility with
    fewer holders than its minimum right now. And any responsibility with
    exactly one active holder, ranked by criticality.
    
    Most companies find two or three they did not know about, and that alone
    justifies the build.
    
    ## 3. Check cover while the answer can still change
    
    Now connect the two halves.
    
    When a request is submitted, take every responsibility that person holds,
    count how many other active holders are available across the whole
    requested window, and compare against the minimum. Three outcomes: clear,
    warning if it sits exactly at the minimum, conflict if it drops below.
    Name the responsibility and the dates.
    
    Show that to the requester at submission, before the approver sees it.
    Most people move a day when they can see the clash themselves, and that
    resolves it without a conversation.
    
    The approver sees the coverage result next to the balance, plus the team
    calendar for that window.
    
    Allow approval over a conflict, with a required reason and a named
    mitigation. Blocking leave makes people route around the system, and a
    recorded decision is what you actually wanted. Then give me a forward view:
    any date in the next six months where a responsibility drops below its
    minimum given the leave already approved.
    
    ## 4. Make cover something that actually happens
    
    For each approved absence, record a named deputy per responsibility,
    defaulting to the secondary holder.
    
    Then track what actually moves, as a checklist with a from and to date:
    approval routing, on-call rota, inbox delegation, system access, and any
    named contact updates. A deputy named on a document changes nothing about
    who can approve a payment on Wednesday.
    
    Notify the deputy on activation with what they are covering and until
    when, and again on the day it ends.
    
    Prompt for a handover note two days before leave starts, which is the last
    moment anybody will write one: what is in flight, what needs a decision,
    who to contact.
    
    And report which responsibilities repeatedly cause conflicts. That list is
    a cross-training or hiring argument with evidence attached.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Workday>. Read entitlements, working patterns and public holidays for
    each person's location.
    
    <Okta>. Read teams and the manager relationship, so a request routes to
    the right approver without a list somebody maintains.
    
    <Google Calendar>. Show the team calendar for the requested window, and
    block the days once approved.
    
    <PagerDuty>. Take somebody off the rota while they are away, which is the
    deputy step people forget.
    
    <Slack>. Set a status and tell the deputy what they are covering and until
    when.
    
    <Jira>. Reassign anything in flight to the deputy rather than leaving it
    queued behind somebody away.
    
    <Gusto>. Read the entitlement and accrual rules that actually apply to
    each contract type.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  25. People

    performance review cycle app

    Run a cycle to a schedule, collect self and peer input before the manager writes, keep ratings comparable across teams, and finish with something the person can act on. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A cycle that keeps its own dates
    
    In this Helix project, build me a performance review cycle app.
    
    A cycle has a name, a period it covers, and dated stages: self-assessment
    opens and closes, peer input opens and closes, manager review closes,
    calibration, then delivery. Derive every stage date as an offset from the
    cycle close, so when the cycle slips a week the whole schedule moves
    instead of somebody editing five dates.
    
    Participants are generated from a list of employees with their manager,
    team, level and start date. Exclude anyone who started after a cut-off I
    set, and flag anyone whose manager changed during the period, because
    those reviews need a conversation rather than a form.
    
    Show me a live view of the cycle: how many self-assessments are in, how
    many peer requests are outstanding, how many manager reviews are drafted
    against submitted, and who is behind. Chase automatically rather than
    through somebody's reminder list.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Manager writes last
    
    Enforce the order, and this is the part that matters most.
    
    Self-assessment opens first. Then peer input. Only when those close does
    the manager see them and start writing.
    
    A manager who writes before reading the self-assessment and the peer input
    writes their impression of the last month, and the whole cycle becomes a
    record of recency rather than of a year. Making the sequence structural
    rather than advisory is the fix.
    
    For peer input: the employee nominates, the manager approves the list, and
    there is a limit on how many requests one person can receive. Without a
    limit, the same three generous colleagues are nominated by everybody and
    spend a fortnight writing reviews.
    
    Ask peers specific questions rather than for general comments. What did
    this person do that helped you, and what one thing would make working with
    them easier. General prompts produce general praise, which is pleasant and
    useless.
    
    ## 3. Ratings that mean the same thing in two teams
    
    Define the rating scale properly, in a config file.
    
    For each point on the scale, write out what it looks like behaviourally,
    and do it per level. What "exceeds" means for a graduate and for a
    principal are different things, and a single generic description means
    each manager silently supplies their own.
    
    Show those descriptions on the screen where the manager selects a rating,
    not in a document nobody opens.
    
    Require evidence for every rating: specific things that happened, not
    adjectives. Do not accept a rating without it.
    
    Separate the rating on what was achieved from the rating on how, if you
    use both, and keep them visibly separate all the way through. Blending
    them into one number is how a company loses the ability to say that
    somebody delivered and was difficult to work with, which is exactly the
    case the review exists for.
    
    ## 4. Calibrate, then deliver
    
    Add a calibration stage between the manager review and delivery.
    
    Managers see proposed ratings across teams, with the distribution per
    team, per level and per manager. Show who rates everybody highly and who
    rates nobody highly, because both are real and neither is visible from
    inside one team.
    
    Let ratings be adjusted during calibration, with a reason recorded and the
    original preserved. Nothing is visible to the employee until calibration
    closes. Changing a rating after somebody has seen it is a much harder
    conversation than changing it before.
    
    Then delivery: the employee sees their review, acknowledges it, and can
    add their own comment, which is kept.
    
    Finish with something to act on: agreed development goals with dates,
    carried into the next cycle so it opens with what was agreed last time.
    Then report completion rate by manager, rating distribution over cycles,
    and time from cycle close to delivery.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Workday>. Read the employee list, managers, levels and start dates to
    generate the cycle, and write the final rating and agreed goals back once
    calibration closes.
    
    <Okta>. Read the manager relationship, which is what the app uses to
    decide who can see a draft and who can see peer feedback.
    
    <Gmail>. Send the formal cycle notices, which people keep and refer back
    to in a way they do not with a chat message.
    
    <Lattice>. If you already run reviews somewhere, read the cycle and write
    results back rather than running two.
    
    <Slack>. Chase self-assessments and peer input against the stage dates,
    which is most of running a cycle.
    
    <Google Drive>. Hold the written review where HR retention rules already
    apply.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  26. Product and Engineering

    feature request tracker

    Collect requests from everywhere, merge the duplicates, weight them by the revenue behind them, and close the loop when something ships. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. One record, whatever the channel
    
    In this Helix project, build me a feature request tracker.
    
    One record per request, whatever channel it arrived through: the
    requester, their account, the source (sales call, support ticket,
    community, field, internal), the date, and the original words exactly as
    they were written. Keep those verbatim. Paraphrasing at intake loses the
    thing you will want to read in six months.
    
    Then two separate fields, and this is the important part: the problem, and
    the proposed solution. People submit solutions. "We need a bulk export
    button" is a solution; "I spend two hours a month copying this into a
    spreadsheet" is the problem, and the problem is what you can actually
    address, sometimes in a way nobody asked for.
    
    Make the intake form take under a minute for someone on a sales call, and
    let me paste in a block of text and have you pull out the fields for me to
    confirm.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Merge, never discard
    
    Now handle the fact that the same request will arrive twenty times in twenty
    different phrasings.
    
    Suggest likely duplicates on submission, matching on wording and on the
    problem field rather than exact text. Show me candidates rather than
    merging automatically.
    
    When I merge, keep every requester, every account and every original
    wording attached to the surviving record. Never delete a duplicate. The
    count of who asked and which accounts they came from is the entire demand
    signal, and discarding a duplicate throws it away.
    
    Let me split a merge back apart when I get it wrong, because I will.
    
    ## 3. Weight it by something real
    
    Now score demand, and do not use a vote count.
    
    For each request, pull in the accounts asking and weight by what is
    actually at stake: total contract value of the requesting accounts,
    whether any of them are at risk or in a renewal window, whether it was
    named as blocking a deal and how large that deal was, and how recently it
    last came up.
    
    Ten asks from one enthusiastic champion is one account asking. One ask
    each from your five largest customers is a different fact entirely, and a
    vote count reports them the same way.
    
    Show the components as well as the total, so a score can be argued with
    specifically. And let me filter by segment, because a request that matters
    enormously to small customers and not at all to enterprise is a real and
    useful pattern rather than a contradiction.
    
    ## 4. Close the loop, or intake dies
    
    Give each request a status that means something to the person who submitted
    it: received, under consideration, planned, in progress, shipped,
    declined, or already possible. Include that last one. A surprising share
    of requests are for something that already exists and nobody found.
    
    When a request changes status, notify everyone attached to it, including
    everyone whose duplicate was merged in. When something ships, say so and
    link to it. When something is declined, say why. A declined request with a
    reason keeps people submitting; silence does not.
    
    Then report: requests by theme over time, which themes have the most
    weighted demand, average age of open requests, and how many shipped items
    came from the tracker at all. That last number tells you whether this is
    a real input to the roadmap or a suggestion box.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read the contract value, renewal risk and open deals behind
    each requesting account.
    
    <Zendesk>. Pull requests that arrived as tickets, which is where a lot of
    them start.
    
    <Jira>. Link a planned request to the work, and read back when it ships.
    
    <Slack>. Tell everyone who asked when something ships, which is what keeps
    intake alive.
    
    <Okta>. Read group membership, which is what lets the app show the field a
    status while product sees the full deal context behind a request.
    
    <Amplitude>. Check whether the people asking actually use the area they
    are asking about.
    
    <Snowflake>. Read contract values in bulk, which is what makes weighting
    200 requests practical.
    
    <Notion>. Publish the shipped list where the field already looks for
    release notes.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  27. Product and Engineering

    bug triage queue

    Score bugs by impact rather than by who reported them, group duplicates onto one defect, and set targets a team can actually hold. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Intake that can actually be worked
    
    In this Helix project, build me a bug triage queue.
    
    A report captures: what happened, what was expected instead, the steps to
    reproduce, the environment (browser, version, platform), how often it
    happens, when it started, the affected account if there is one, and who
    reported it.
    
    Require the steps. A bug with no reproduction steps is a conversation
    rather than a ticket, and the form should say so before it is submitted
    rather than an engineer discovering it three days later.
    
    Let people attach screenshots, recordings and log excerpts.
    
    And let me paste in a support ticket or a Slack message and have you draft
    the fields for me to correct, because most bugs arrive as prose from
    somebody who is annoyed.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Severity that the reporter does not choose
    
    Now severity, and do not give the reporter a dropdown. Everyone rates their
    own bug highest, and within a month the queue is sorted by confidence
    rather than by damage.
    
    Instead ask a short set of questions and derive the level: how many people
    are affected, is there a workaround and how painful is it, is data being
    lost or corrupted, is anything exposed that should not be, is it getting
    worse, and does it block a customer commitment.
    
    Put the derivation in a config file so I can tune it, and show the answers
    alongside the resulting severity so anybody can see why a bug sits where
    it does.
    
    Let a triager override the derived level, with a reason. Log the
    overrides, and report on them. If one person overrides constantly, either
    the rules are wrong or the triage is.
    
    ## 3. One defect, however many people hit it
    
    Handle duplicates by grouping rather than closing.
    
    Suggest likely matches on submission using the symptom description and the
    environment. When reports are grouped onto one defect, keep every reporter
    and every affected account attached.
    
    Then feed that count straight back into severity. Twenty people hitting
    one bug is a stronger signal than one person hitting it, and twenty
    separate tickets both hides that and inflates how much work there appears
    to be.
    
    Let me split a group apart when two things turn out to be different bugs,
    and keep the history of the split.
    
    ## 4. Targets, and the two clocks that fail differently
    
    Set targets per severity in the config: time to first triage, and time to
    fix or to a stated workaround. Report against both.
    
    Keep those two clocks separate. Slow triage means nobody is looking at the
    queue. Slow fixing means the work is hard or the team is loaded. They fail
    for different reasons and a single time-to-close number hides which one
    you have.
    
    Show a queue sorted by severity then age, with anything past its triage
    target at the top.
    
    Then reporting: bugs by area and severity over time, reopen rate, the
    proportion arriving from customers versus found internally, and the age of
    the oldest untriaged bug, which is usually more informative than the
    average.
    
    And keep a list of known issues with workarounds that support can search,
    because a large share of new reports are things you already know about.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Zendesk>. Pull customer-reported bugs with their account attached, so
    severity can weigh who hit it.
    
    <Jira>. Push triaged defects to engineering and read status back, rather
    than keeping two lists.
    
    <Salesforce>. Read the contract value behind the affected accounts, which
    is an input to severity.
    
    <Datadog>. Read the logs and traces around the same request, which is what
    turns a vague report into a reproduction.
    
    <Sentry>. Read the error signature and how often it fires, which usually
    settles reproduction.
    
    <Slack>. Route a severity one to the team that owns the service, not to a
    shared channel.
    
    <Okta>. Attribute every triage decision and severity override to a
    verified person.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  28. Product and Engineering

    release readiness checklist app

    Generate the right checks for the kind of release it is, block on the ones that matter, and tell the teams who need to know before it ships. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Checks that match the release
    
    In this Helix project, build me a release readiness app.
    
    Start with the release record: name, version, planned date, owner, the
    changes it contains, and a set of attributes I tick. Seed the attributes
    with: contains a schema migration, changes pricing or billing, is visible
    to customers, adds a third-party dependency, changes permissions or
    access, touches data retention, requires a configuration change, needs
    documentation.
    
    Then keep check templates in a config file, each one saying which
    attributes it applies to, which team owns it, and whether it blocks.
    
    Creating a release generates its checklist from the attributes ticked.
    A copy change should produce four checks and a schema migration should
    produce fifteen. One list for every release gets ticked without being
    read, and that is worse than no list because it looks like diligence.
    
    Show me which templates matched and why, so I can see how a list was
    assembled.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Block on little, record everything
    
    Split checks into blocking and advisory.
    
    Blocking checks genuinely stop the release: the migration has been tested
    against a production-sized copy, there is a rollback plan, the on-call
    engineer knows it is going out. Keep that set small.
    
    Advisory checks are recorded but do not block: documentation drafted,
    changelog written, screenshots updated.
    
    Let somebody skip a blocking check with a named approver and a written
    reason, and report those skips. A control with no override gets bypassed
    entirely; a control with a recorded override stays a control.
    
    Show progress as two numbers rather than one percentage: blocking checks
    outstanding, and advisory checks outstanding. A release at ninety percent
    overall with one blocker outstanding is not ninety percent ready.
    
    ## 3. Tell the teams who deal with it
    
    Add cross-team readiness.
    
    For releases with customer-visible changes, require confirmation from
    support, customer success, sales and documentation that they know what is
    coming and are ready for it. For everything else, notify them without
    blocking.
    
    Give each of those teams a view of what is coming in the next two weeks,
    filtered to the releases that actually affect them.
    
    Include a "what to tell a customer" field on any customer-visible release,
    written by whoever owns the release and reviewed by support. That single
    field prevents most of the calls that start with somebody's colleague
    saying they were not told.
    
    And let support flag a concern that becomes a blocking item, so the
    escalation path exists before somebody has to invent one on the day.
    
    ## 4. The record, and what you learn from it
    
    On ship, record what actually went out: the date, the version, the contents,
    which checks passed, which were skipped and by whom with what reason, and
    the known issues at ship time.
    
    Make known issues visible to support immediately. Finding out from a
    customer is the expensive version of that conversation.
    
    Keep the completed checklist. When something breaks the next morning, the
    first question is what changed, and this answers it faster than anything
    else you have.
    
    Then report: releases per period, blocking checks skipped and by whom,
    which checks are always ticked without comment (those are candidates for
    removal), and how often a release is followed by an incident, broken down
    by which attributes it had. That last one tells you whether the
    attribute-based generation is calibrated.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <GitHub>. Read the changes in a release, which is what the attributes are
    derived from.
    
    <Jira>. Link the release to the work it closes, and back to any incident
    afterwards.
    
    <Slack>. Tell support, success and documentation what is coming before it
    ships, not after.
    
    <Okta>. Read group membership so a check belongs to a real team, and
    attribute every skipped one to a verified person.
    
    <LaunchDarkly>. Read which flags are on for this release, since a flag
    flip is a change the checklist should know about.
    
    <Datadog>. Watch the verification window after a release, and link
    anything that fires back to it.
    
    <Zendesk>. Give support the known issues at ship time, so they hear it
    from you and not a customer.
    
    <Notion>. Publish the changelog where the rest of the company already
    reads it.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  29. Product and Engineering

    product launch tracker

    One launch, six workstreams, one readiness view, and a go or no-go that is a decision rather than a vibe. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Tier the launch before anything else
    
    In this Helix project, build me a product launch tracker.
    
    A launch record: name, the feature or release it covers, the product area,
    the target date, the launch tier, the launch owner, current status, and a
    one-line description of what changes for the customer.
    
    Tiers, and make this the first decision:
    
    Tier one is a major launch. Press, analysts, a campaign, sales
    enablement, a customer webinar.
    Tier two is a significant feature. Release note, docs, an email, a sales
    briefing.
    Tier three is an incremental change. Release note and docs only.
    
    The tier determines which workstreams apply and which exit criteria are
    required, so let me define that mapping and change it.
    
    Treating every feature as a tier one exhausts the company and people stop
    reading launch emails. Treating none of them as one means the launch that
    mattered lands with support seeing it for the first time in a ticket.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. A workstream per function, each with its own readiness
    
    Now add workstreams, one per function involved: product, documentation,
    marketing, sales enablement, support, legal and privacy, and anything else
    I add later.
    
    Each workstream on a launch has a named owner, a set of tasks derived from
    the tier, its own readiness percentage, and a status the owner sets:
    on track, at risk, or blocked.
    
    Show readiness per workstream rather than one blended number. "Marketing
    is 60%" tells you who to call. "The launch is 78% ready" tells you
    nothing, and it is usually an average that hides one workstream at zero.
    
    Roll up to a launch view: which workstreams are ready, which are at risk,
    and specifically what is outstanding in each.
    
    Let workstream owners update their own status without touching anyone
    else's, because a launch tracker that only the launch owner can edit
    becomes the launch owner chasing seven people on Slack, which is the
    thing you were trying to replace.
    
    ## 3. Exit criteria you can check rather than feel
    
    Add exit criteria per workstream per tier, and make them checkable.
    
    Not "docs are ready" but the specific thing: the three how-to pages are
    published and linked from the release note. Not "sales is enabled" but
    the briefing is delivered, the one-pager is in the portal, and the demo
    environment has the feature switched on.
    
    Each criterion is either met or not, with who confirmed it and when. The
    workstream readiness percentage is then just the proportion met, which
    makes it a measurement rather than an opinion.
    
    Track the ship date and readiness as separate questions. If they are the
    same field, readiness quietly becomes whatever the date needs it to be,
    and you find out on launch day.
    
    Flag any criterion marked met with no evidence and no date, because those
    are the ones that turn out not to be met.
    
    ## 4. A go or no-go that is a decision
    
    Last, the decision, and treat it as an event rather than an email thread.
    
    A go or no-go on a date before the launch: it shows every workstream's
    readiness, the outstanding criteria, the risks raised, and it records an
    outcome. Go, go with a named exception, or no-go with a new date.
    
    Record who decided and what they knew. A launch that goes with docs at
    40% is sometimes the right call, and the useful thing is that somebody
    chose it with the number in front of them rather than nobody noticing.
    
    Keep the no-go decisions. The launches you delayed and why are the most
    useful history a launch function has, and they are the ones that never
    get written down.
    
    Then report across launches: how many by tier per quarter, which
    workstream is most often the one at risk, average slip by tier, and the
    proportion that went with exceptions. If the same workstream is late
    every time, that is a resourcing answer rather than a nagging problem.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Jira>. Read the epic behind the launch, so the product workstream's
    readiness is the real state of the work rather than a typed percentage.
    
    <Slack>. Give each launch a channel, and post the readiness summary before
    the go or no-go rather than asking seven people.
    
    <Notion>. Pull the launch brief, positioning and messaging, so the tracker
    links to them rather than duplicating them.
    
    <Salesforce>. Read which accounts asked for this, which is what turns a
    launch email into a list of calls worth making.
    
    <Google Calendar>. Hold the launch date and the go or no-go, so the date
    lives in one place and moves in one place.
    
    <Zendesk>. Confirm support macros and help centre articles exist, which is
    the support workstream's exit criterion rather than a promise.
    
    <Google Drive>. Track the enablement deck and one-pager as artefacts, so
    'the briefing is delivered' has something attached to it.
    
    <Amplitude>. Read adoption after launch, which is the only way to know
    whether a tier one was worth being a tier one.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  30. Data and Analytics

    metric definitions catalogue

    One definition per metric, owned by a named person, versioned when it changes, and linked to every report that uses it. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. One definition, in language a person can argue with
    
    In this Helix project, build me a metric definitions catalogue.
    
    Each metric has a name, a short business definition in plain language, the
    question it answers, its grain (per what, per when), the unit, and a
    worked example with real-ish numbers.
    
    Then, and this is the field most catalogues leave out, an explicit list of
    what the metric deliberately excludes. Most disagreements about a number
    are about the exclusions rather than the inclusions: does revenue include
    services, does an active user include internal accounts, does pipeline
    include renewals. Write those down as their own field and half the
    arguments stop.
    
    Keep the technical detail as supporting information: source tables, the
    query or transformation, the refresh cadence. Useful, but not the
    definition. A definition only an analyst can read cannot settle an
    argument in a leadership meeting.
    
    Let me tag metrics by domain and search across everything, including the
    exclusions.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. An owner in the business
    
    Give every metric a named owner, and require it. Not the data team: somebody
    in the function that uses the number and would defend it in a meeting.
    
    Add a reviewer too, usually from the data team, who checks that the
    definition and the query actually agree.
    
    Flag any metric with no owner, and any metric whose owner has left, if I
    give you a list of current staff.
    
    Then let anybody raise a question or a proposed change against a metric.
    It routes to the owner, they respond, and the exchange is kept on the
    metric. Six months later the useful artefact is often not the definition
    but the record of why it is that and not the obvious alternative.
    
    ## 3. Version it, do not edit it
    
    Make definitions versioned, with an effective date and a note of what changed
    and why.
    
    Never edit a published version in place. If revenue stops including
    services in April, a number calculated in March was not wrong, and editing
    the definition makes it look as though it was. Anyone reading a historical
    report needs to see which version applied at the time.
    
    Show a diff between versions, and show which version was in force on any
    date I pick.
    
    Add a status: draft, active, deprecated, and replaced by. Deprecated
    metrics stay visible with a pointer to their replacement, because they
    will keep turning up in old decks for years and people need somewhere to
    land.
    
    ## 4. Show what breaks before it breaks
    
    Link each metric to what uses it: dashboards, scheduled reports, models,
    and any app that reads it.
    
    Then when somebody proposes a change, show the full list of what depends
    on that definition. Changing a metric is not a data task, it is a
    communications task, and the list of affected reports is the audience.
    
    Add a conflict report: metrics with similar names or similar definitions
    that are not linked. That is where the three-numbers-for-revenue problem
    actually lives, and it is invisible until something goes looking for it.
    
    Report coverage too: how many metrics used in dashboards have no catalogue
    entry at all. That number starts high and it is the honest measure of
    whether the catalogue is finished.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Looker>. Read which dashboards use which metric, so a proposed change
    comes with its blast radius.
    
    <Snowflake>. Read table and column metadata, so a definition can be
    checked against what the query actually does.
    
    <Okta>. Resolve metric owners to real people, and flag any whose owner has
    left.
    
    <Slack>. Route a proposed change to the owner and keep the exchange on the
    metric.
    
    <dbt>. Read the models behind a metric, so the definition can be checked
    against the transformation rather than the dashboard.
    
    <Google Sheets>. Catch the metrics that only exist in a spreadsheet, which
    is where the disputed ones usually live.
    
    <Notion>. Mirror each definition into the docs space, so somebody
    searching a metric name finds the definition and not a dashboard.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  31. Data and Analytics

    data quality monitor

    Check freshness, volume, nulls and referential integrity on the tables people actually use, with an owner per check and alerts nobody learns to ignore. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Check the things a green pipeline hides
    
    In this Helix project, build me a data quality monitor.
    
    Start with the checks that catch the failure nobody notices: a job that
    succeeds and delivers nothing.
    
    Freshness: how long since this table last received a row, against an
    expectation per table. Volume: how many rows arrived in the last period,
    against what normally arrives. Those two catch more real problems than
    everything else combined, because a pipeline reporting success while
    silently delivering an empty file is the classic six-weeks-wrong scenario.
    
    Then the rest: null rate on fields that should never be null, uniqueness
    on anything that is meant to be a key, referential integrity between
    tables that should join cleanly, and range checks on the numbers people
    quote in meetings.
    
    Let me register which tables to watch rather than watching everything.
    Coverage of the tables people actually use beats coverage of the
    warehouse.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Thresholds learned, not guessed
    
    Now set the thresholds, and do not ask me to invent them.
    
    For each check, look at how the table has actually behaved over a period I
    choose and propose a threshold from that: the normal range, and how far
    outside it is genuinely unusual. Show me the history and the proposal, and
    let me accept or adjust.
    
    Handle the obvious seasonality. A table that is quiet at weekends should
    not alert every Saturday, and one that spikes at month end should not
    alert every month end.
    
    Let me mark a failure as expected, with a reason, and use those to suggest
    threshold adjustments. A check that is dismissed as expected three times
    is a check with the wrong threshold, and the app should say so rather than
    waiting for somebody to notice.
    
    ## 3. Alert a person, not a channel
    
    Give every monitored table a named owner and alert them directly.
    
    A shared channel is where alerts go to be scrolled past. If a check fails
    and nobody is individually responsible for it, nobody is.
    
    Set severity per check, and make it drive the response: a critical
    freshness failure on a table feeding the executive dashboard is not the
    same as a null rate drifting on a field nobody reads. Only the critical
    ones should reach anybody out of hours.
    
    Group alerts. If a source system is down, twelve tables fail at once and
    that is one alert about one cause, not twelve about twelve symptoms.
    
    And show downstream impact in the alert itself: which dashboards and
    reports depend on this table. An owner who can see that the board pack
    reads from it will respond differently.
    
    ## 4. Keep the failures, find the pattern
    
    Record every failure: which check, which table, when it started, when it
    cleared, who resolved it, and what they found.
    
    Then report the things no individual alert can tell you. Which tables fail
    most often. Which upstream sources are behind those failures. Mean time to
    resolution by owner. And checks that have never fired, which are either
    well-behaved tables or badly configured checks, and it is worth knowing
    which.
    
    Add a simple status page showing every monitored table, when it was last
    checked, and whether it is currently healthy. Put the last check time on
    it prominently: a monitor that has itself stopped running is the worst
    possible failure, because everything looks fine.
    
    And report coverage: which tables that feed a dashboard have no checks at
    all. That gap is where the next six-week problem is waiting.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Snowflake>. Run the checks on a schedule. Read-only access, scoped to the
    tables you register.
    
    <Looker>. Read which dashboards depend on a table, so the alert can say
    what breaks downstream.
    
    <PagerDuty>. Alert the named table owner, and only page for the critical
    ones.
    
    <Okta>. Turn the owner recorded against a table into a real person with a
    current address, and flag any whose account has gone.
    
    <dbt>. Read test results you already run, so this monitors what dbt does
    not rather than duplicating it.
    
    <Fivetran>. Read sync status, which explains a freshness failure before
    anyone starts debugging the table.
    
    <Slack>. Alert the named table owner, with the downstream dashboards
    listed in the message.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  32. Data and Analytics

    report request queue

    Ask for the decision rather than the columns, check whether the answer already exists, prioritise against capacity, and turn repeat requests into something self-serve. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Ask what they are deciding
    
    In this Helix project, build me a report request queue for our data team.
    
    The form asks for the usual things: requester, team, what they want, and
    any filters or breakdowns.
    
    But lead with a different question, and make it required: what decision
    will this inform, and what would you do differently depending on the
    answer.
    
    People ask for a spreadsheet with six columns. Once you know they are
    deciding whether to renew a contract, you can often answer it in a
    sentence, or point at a dashboard built last quarter, or realise the
    six columns would not actually have told them.
    
    Then ask for the date the decision is made, not the date they want the
    report. Those are different, and only the first one is real. Ask for the
    difference explicitly if the two dates are far apart.
    
    And ask how they will use it: a one-off answer, something they need
    monthly, or something they want to look at whenever. That answer decides
    whether this is a query or a dashboard, and it is much cheaper to know now.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Check whether it already exists
    
    Before anything is triaged, search what we already have.
    
    Let me register existing reports and dashboards with their name,
    description, what questions they answer, the owner and a link. Then on
    submission, search those against the request text and the decision, and
    show the requester likely matches immediately.
    
    Let them close their own request by saying one of those answered it, and
    record that. That count is the size of the search problem, and it is
    usually large enough to be worth fixing separately.
    
    Also check open requests, so two people asking for the same thing in the
    same week become one piece of work with two people notified.
    
    ## 3. Prioritise against what the team can do
    
    Score each request on the size of the decision it informs, the real
    deadline, and the estimated effort, with the weights in a config file I
    can edit. Effort is estimated by the team, not the requester.
    
    Then rank against capacity: who is available, for how long, and what they
    are already committed to. Draw a line where capacity runs out and show
    what falls below it.
    
    Do not hide the below-the-line list. A queue with no capacity model just
    re-sorts a list longer than the team can deliver, and everybody stays
    disappointed without understanding why.
    
    Let a leader override the order with a reason, and log every override.
    
    Track time in each status, and report time waiting on the requester
    separately. A meaningful share of what looks like data team delay is a
    request sitting with the person who raised it waiting for a clarification.
    
    ## 4. Turn repeats into self-serve
    
    Tag every request with a topic, and report which topics recur.
    
    Three requests for the same thing is a dashboard. Make that an explicit
    action: promote a repeated request into a self-serve report, register it
    in the existing-reports list, and notify everyone who has ever asked for
    that topic that it now exists.
    
    This is the only mechanism that reduces the queue rather than processing
    it faster, and without it a data team stays a helpdesk regardless of how
    efficient it gets.
    
    Then two reports. One for the team: requests by topic, by requesting team,
    turnaround, and the proportion answered by pointing at something that
    already existed. And one that is uncomfortable: for delivered requests,
    did the answer change the decision. Ask the requester a fortnight later.
    A high proportion of no is the most useful thing this app will ever tell
    you.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Looker>. Read the existing reports and dashboards, so a submission can be
    matched against them immediately.
    
    <Okta>. Resolve requesters, their teams and the analyst group you assign
    to, so none of it depends on a list somebody maintains.
    
    <Slack>. Tell everyone who ever asked for a topic when it becomes a self-
    serve dashboard.
    
    <Jira>. Push accepted requests to wherever the team actually works, rather
    than a second queue.
    
    <Snowflake>. Check whether the data a request needs actually exists before
    it is scheduled.
    
    <Google Sheets>. Deliver one-off answers where requesters will actually
    use them.
    
    <Notion>. Publish the self-serve reports so a repeated request becomes a
    link.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  33. Data and Analytics

    executive KPI dashboard

    A small set of numbers everyone agrees on, each with a target, a trend and a named owner, refreshed on a schedule that is visible. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The short list, and saying no to the rest
    
    In this Helix project, build me an executive KPI dashboard.
    
    A metrics table: name, a one-line definition in business language, the
    function it belongs to, the unit, the target for the current period, a
    named owner, and how often it refreshes.
    
    Keep the list short. Ten to fifteen. Build a hard cap into the app with a
    warning when somebody tries to exceed it, because the pressure will
    always be to add rather than remove, and a dashboard with forty numbers
    is a report nobody reads.
    
    Require an owner on every metric, and require a target. A metric with no
    target produces a discussion, and a metric with no owner produces a
    question nobody answers.
    
    Link each metric to its full definition, including what it deliberately
    excludes. Most leadership disagreements about a number are about the
    exclusions, and having the answer one click away saves the first twenty
    minutes of the meeting.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Trend and target, together
    
    Now the display, and never show a bare number.
    
    For each metric: the current value, the previous period, the same period
    last year, the change as an amount and a percentage, the direction, and
    progress against target.
    
    Chart the trend rather than only the latest figure. A leadership team
    needs to know whether something is improving, and a single number cannot
    say.
    
    Colour by whether the metric is on track against its target, not by
    whether it went up. Some metrics going up is bad, and a dashboard that
    does not know which is which teaches people to ignore the colour.
    
    Handle missing data honestly. If a metric has not refreshed, say so
    rather than showing the last known value as though it were current.
    
    ## 3. Make staleness visible
    
    Add refresh handling, and put it on the page rather than in a log.
    
    Each metric records when it last updated successfully and what its
    expected cadence is. Show the timestamp next to the number, and flag
    anything that has missed its cadence.
    
    If a source fails, the metric shows as stale rather than showing an old
    figure as current. A number nobody knows is out of date is the one that
    ends up quoted in a board pack.
    
    Let me snapshot the whole dashboard at period end and keep it, so what
    was reported in September still reads the same in December even after the
    underlying data is corrected. Corrections then show as a difference
    between the snapshot and the live figure, which is a useful thing to see
    rather than a problem to hide.
    
    ## 4. Commentary, and the drill-down
    
    Two last things.
    
    Let the owner of each metric add a short comment for the period: what
    moved, why, and what they are doing about it. Prompt for it before the
    meeting rather than during. A number with the owner's explanation
    attached is a decision; a number alone is an agenda item.
    
    And let me drill from any metric to the detail behind it, or link out to
    the functional dashboard that owns it. The executive view should be the
    top of a path rather than a dead end.
    
    Then report: metrics on and off target over time, which metrics change
    owner or definition most often, which is usually a sign the metric is not
    settled, and how often each metric was stale when the meeting happened.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Snowflake>. Read most metrics from the warehouse, where the definitions
    have already been applied consistently.
    
    <Salesforce>. Read pipeline, bookings and retention where they are not
    already modelled in the warehouse.
    
    <NetSuite>. Read revenue, margin and cash figures for the finance metrics.
    
    <Looker>. Link each metric to the functional dashboard that owns it, so
    the executive view is the top of a path rather than a dead end.
    
    <Okta>. Read the group that says who is on the leadership list, which is
    the only thing the app should check before showing performance against
    target.
    
    <Amplitude>. Read product engagement metrics, which are usually the ones
    missing from the finance systems.
    
    <Zendesk>. Read support volume and satisfaction, which leadership asks
    about and nobody has to hand.
    
    <Slack>. Remind each owner to write their commentary before the meeting
    rather than during it.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  34. IT and Operations

    access request and approval app

    Request access against a defined catalogue, route it to the system owner, grant it with an expiry, and produce the evidence an access review needs. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The catalogue, written for the approver
    
    In this Helix project, build me an access request and approval app.
    
    Start with a catalogue. Every system: name, description, a named owner,
    sensitivity from low to restricted, whether it holds personal data, and
    whether it is in scope for any compliance regime. Then the roles available
    in each system, with a default grant duration, whether it can be permanent
    at all, and whether it needs a second approver.
    
    Now the field that matters most. For every role, write a plain-language
    description of what it actually lets somebody do, aimed at an approver
    rather than an administrator. "Can read and export all customer records
    including contact details" is useful. "db_reader" is not, and an approver
    who cannot tell what they are granting will grant everything.
    
    Make the catalogue browsable and searchable, with sensitivity clearly
    shown. And flag any system with no named owner and any role with no
    description, because both make every downstream approval meaningless.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Route it to somebody who can actually judge it
    
    Requests need a business justification in free text plus a reason from a
    short fixed list, and reject empty justifications.
    
    Route to the system owner. Add the requester's manager as a required first
    step where the role sensitivity is high or restricted.
    
    Show the approver: who is asking, their role and team, what this access
    permits in plain language, what access they already hold, and whether
    people in comparable roles have it. That third item is the one that
    catches slow accumulation, where somebody has quietly ended up able to do
    everything because each individual request looked reasonable.
    
    Give every approver a deputy with automatic reroute. Access requests that
    stall get solved by asking a colleague directly, which is exactly the
    behaviour this app exists to replace.
    
    ## 3. Make access expire
    
    Keep grants separate from requests. What was asked for and what was given
    are not always the same, and that difference is exactly what an auditor
    asks about.
    
    A grant records the person, system, role, when it was granted and by whom,
    when it expires, and if revoked, when and why.
    
    Default the expiry from the role's duration. Permanent requires an
    explicit choice and a reason, and reports separately so I can see how much
    of it there is.
    
    Notify the holder and the system owner before expiry, with a one-click
    extension request that goes back through approval rather than renewing
    automatically. An auto-renewing grant is a permanent grant with extra
    steps.
    
    On expiry, mark it expired and create a revocation task for the system
    owner, with evidence required on completion. Then give me the view
    everybody wants and almost nobody has: current access, per person and per
    system.
    
    ## 4. Reviews that are honest about themselves
    
    Generate a review per system on a schedule. The system owner sees every
    current grant and confirms, reduces or revokes each one, with a reason
    required for anything revoked.
    
    Anything not reviewed by the due date reports as not reviewed. Do not
    auto-confirm and do not auto-revoke. Both hide the fact that the review
    did not happen, and the whole point is to know.
    
    Produce a review record: what was confirmed, what was revoked, what was
    not reviewed, by whom and when. Exportable.
    
    Then standing reports: permanent grants by system, people holding access
    to more than a threshold number of high-sensitivity systems, access
    granted but never used if I can give you login data, and grants belonging
    to people who have left.
    
    That last one should be empty. When it is not, it is the most urgent thing
    in the app.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Okta>. Read groups and roles, and provision or revoke access when a grant
    starts and expires.
    
    <each target system>. Grant and remove the specific role, and record the
    evidence that it happened.
    
    <Workday>. Read leavers, so the report of people who left still holding
    access is real.
    
    <Slack>. Route a request to the system owner and warn a holder before a
    grant expires.
    
    <Google Workspace admin>. Grant and remove access to files, groups and
    shared drives, which is where a lot of real access lives.
    
    <Jira>. Raise the revocation task for systems that cannot be automated, so
    it is tracked rather than remembered.
    
    <Vanta>. Feed the access review evidence in, so the review is recorded
    where audits get answered from.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  35. IT and Operations

    IT asset and licence tracker

    One record per device and licence, with an assignment history, a lifecycle, and a reconciliation against what your systems actually report. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Assets with a state that means something
    
    In this Helix project, build me an IT asset and licence tracker.
    
    Assets first: asset tag, type, make, model, serial number, purchase date
    and cost, supplier, warranty expiry, expected replacement date, condition,
    location, and a lifecycle state.
    
    Make the state a fixed list, not free text: ordered, in stock, assigned,
    in repair, lost, retired, disposed. Record every state change with a
    timestamp, who changed it and why. Lifecycle drives both cost reporting
    and risk reporting, and it cannot be a location field with words in it.
    
    Derive depreciation from the purchase cost and a schedule I configure per
    asset type, and show the current book value. Flag anything past its
    expected replacement date, and anything with warranty expiring in the next
    90 days.
    
    Import from CSV with the column mapping in one editable file.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Assignment as history
    
    Now assignment, and do not put a current-holder field on the asset.
    
    Instead, assignment is a row: asset, person, assigned at, assigned by,
    returned at, returned condition, notes. The current holder is derived from
    the row that has no return date. Returning closes a row, assigning opens a
    new one, and the full history stays intact.
    
    Overwriting a holder field deletes the answer to who had this device in
    June, which is precisely the question a security investigation asks.
    
    Give me a view per person of everything currently assigned and everything
    they have ever held, and a view per asset of the whole chain of custody.
    
    Add an acceptance step: when an asset is assigned, the recipient confirms
    receipt and condition, and that confirmation is recorded.
    
    And if I give you a list of current staff, flag any asset assigned to
    somebody no longer active. That list should be empty and it rarely is.
    
    ## 3. Licences, which cost more and get tracked less
    
    Licences get their own records: vendor, product, licence type, total seats,
    cost per seat, annual cost, term start and end, auto renew, notice period,
    contract reference and owner.
    
    Assignments use the same history model as assets, for the same reason,
    plus a last-used date per person.
    
    Derive seats used, seats free, and the annual value of unassigned seats.
    Then a reclaim list: assignments where last used is older than a threshold
    I set, ranked by what reclaiming them is worth.
    
    Sort the renewal view by notice deadline, which is term end minus notice
    period, rather than by term end. Sorting by term end shows me contracts I
    can no longer cancel.
    
    And flag licences assigned to inactive people, which is a cost problem and
    an access problem at the same time.
    
    ## 4. Check the register against reality
    
    Import a device list from device management and a user list from the
    identity provider, on a schedule.
    
    Produce three lists. Assets we know about and management can see. Assets
    we know about that have not been seen for longer than a threshold. And
    devices management can see that are not in the register at all.
    
    That third list is the one that grows on its own, and it is exactly what a
    manual inventory cannot find.
    
    Match on serial number first, then asset tag, then hostname. Show the last
    successful import time on every page, and say so clearly when an import
    fails rather than serving stale data quietly.
    
    Then reporting: asset count and value by type, state and location;
    replacement spend by quarter; average age of assigned devices; unassigned
    licence value; and everything held by people who have left. Plus an audit
    export of every asset with its full assignment history for a period.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Jamf>. Read every device it can see, which produces the list of hardware
    nobody registered.
    
    <Okta>. Read current staff, so assets and licences held by leavers surface
    immediately.
    
    <each vendor admin API>. Read assigned seats per tool, which is how you
    find licences still allocated to people who left.
    
    <NetSuite>. Read the purchase record and the capitalised value, so the
    register agrees with what finance has on the balance sheet.
    
    <Intune>. Read Windows devices, since most estates are not one platform
    whatever the standard says.
    
    <Coupa>. Read purchase records and warranty terms rather than retyping
    them.
    
    <Slack>. Ask somebody to confirm they still have a device the register has
    not seen for a while.
    
    <Snowflake>. Keep a dated snapshot of the register, so what we owned and
    paid for last March is answerable and not just what is true today.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  36. IT and Operations

    incident and postmortem tracker

    Record incidents with a consistent timeline, run postmortems to a fixed template, and track the action items until they are actually done. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Capture it while it is happening
    
    In this Helix project, build me an incident and postmortem tracker.
    
    Severity levels go in a config file: for each, the customer impact that
    qualifies, the required response time, who to notify, and whether a
    postmortem is mandatory.
    
    An incident records the title, severity, services affected, customer
    impact, how many customers, how it was detected, the incident commander,
    the communications lead, and four timestamps: started, detected,
    acknowledged, mitigated, plus resolved.
    
    Then a timeline that gets written during the incident, not afterwards.
    Adding an entry has to take one field and one click, because nobody writes
    carefully while an outage is running. Entry types: observation, action,
    decision, communication.
    
    Derive time to detect, time to acknowledge and time to mitigate, and show
    them separately. Total duration alone hides whether the problem is
    monitoring or runbooks, and those need completely different investment.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. The postmortem, same shape every time
    
    Postmortems use one fixed template: summary, customer impact, timeline
    pre-filled from the live entries, trigger, contributing factors, detection
    analysis, response analysis, what went well, what was difficult, lessons.
    
    Separate the trigger from the contributing factors and allow several
    factors. Most incidents have one trigger and a handful of conditions that
    made it possible or made it worse, and collapsing that into a single root
    cause throws away the actionable half.
    
    Keep the structure blameless. Do not add a field asking who made the
    change. Ask what made the change safe to make and hard to catch. A
    blameless tone attached to a blame-shaped template produces a blame
    analysis anyway, however politely it is worded.
    
    Give it a review state, let people comment on a draft without editing it,
    and publish to a searchable archive tagged by service and factor type.
    
    ## 3. Action items that survive the meeting
    
    Make action items independent records, not bullet points inside a document.
    
    Each has a description, a type (prevent recurrence, improve detection,
    improve response, reduce impact), an owner, a due date, a priority, a
    status, and evidence of completion.
    
    They are created from a postmortem but they live on their own. Publishing
    the postmortem does not close them, because publishing is exactly the
    moment attention leaves the room.
    
    Do not allow an item without a named owner and a due date. An item owned
    by a team is owned by nobody.
    
    Give me an owner view across all incidents, a team view, weekly reminders
    for overdue items, and escalation to a manager past a threshold. Then
    report completion rate by type and team, and the age of the oldest open
    item, which is usually more informative than the average.
    
    ## 4. Find out whether any of it is working
    
    Report incidents by severity, service and month. Tag contributing factors
    from a fixed editable list and report them by frequency. That list tells
    you where to invest.
    
    Then build repeat detection: incidents sharing a service and a contributing
    factor within a window I set. Surface those as repeats.
    
    And when a repeat has an incomplete action item from the earlier incident,
    highlight it loudly. That single connection is the most persuasive report
    an operations team can put in front of a leadership meeting.
    
    Trend time to detect and time to mitigate per service over time. And build
    a quarterly review view that assembles itself: every incident in the
    period, the factors behind them, action item completion, and the repeats.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Datadog>. Read the alert that fired and when, which is where time to
    detect comes from.
    
    <Jira>. Push action items to where the team actually works, so they are
    not orphaned in a document.
    
    <GitHub>. Read what shipped near the incident, which is the first question
    anybody asks.
    
    <Slack>. Capture the incident channel into the timeline, so it is not
    reconstructed from memory.
    
    <PagerDuty>. Read who was paged and when, which is where time to
    acknowledge actually comes from.
    
    <Statuspage>. Read what customers were told and when, so the timeline
    includes the communications.
    
    <Zendesk>. Link the tickets the incident generated, which is the honest
    measure of customer impact.
    
    <Notion>. Publish the postmortem where engineering already reads, with the
    action items linked back.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  37. IT and Operations

    change request log

    Record every production change with a risk level, an approval proportionate to that risk, and a rollback plan, without turning deployment into a committee. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Make filing fast, or the log will be empty
    
    In this Helix project, build me a change request log.
    
    The design constraint that beats everything else: filing a routine change
    has to take under a minute. A heavy process gets bypassed, and a bypassed
    log is worse than no log because it looks complete.
    
    So define standard change types in a config file: the routine things like a
    dependency bump, a config value inside a known range, a scheduled restart,
    a documented data fix. Each says which systems it applies to and that it
    is pre-approved.
    
    For everything else, derive the risk level from a short questionnaire
    rather than asking someone to pick one. Does it touch customer data. Is it
    reversible. Does it need downtime. Has this type of change caused an
    incident before. Deriving it removes the guesswork and the incentive to
    under-rate.
    
    Record: title, description, systems affected, type, risk, requester,
    implementer, planned and actual windows, related ticket or pull request,
    and outcome.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Approval proportionate to risk
    
    Standard changes are pre-approved by type. Log them anyway, with no
    approver. The log has to be complete to be worth anything.
    
    Normal changes route to the owner of each affected system, with a second
    approver above a risk threshold I set.
    
    Emergency changes get implemented first, filed within a window I
    configure, then reviewed retrospectively by a named reviewer. Build that
    path deliberately. A process with no emergency route does not stop
    emergency changes, it just loses the record of them.
    
    Show approvers what is changing, the risk answers, the rollback plan, the
    window, and any incidents previously linked to this system or change type.
    
    Deputies for every approver with automatic reroute, because a change
    waiting on somebody who is away is a change that happens without a
    record.
    
    ## 3. Write the rollback while there is time to think
    
    Require a rollback plan on every non-standard change: the steps, how long
    it should take, and the signal that would trigger it. Writing that during
    an incident is when it is least likely to be right, and the person
    responding may not be the person who made the change.
    
    Require a verification plan too: how the implementer will confirm it
    worked, and over what period.
    
    On execution, record the actual window and the outcome from a fixed list:
    successful, successful with issues, rolled back, failed. Anything other
    than successful needs a short explanation and a note of whether an
    incident was raised.
    
    Add a change calendar by system and window, with a warning when two
    changes touch the same system at the same time. And optional freeze
    periods, with an override that requires a reason.
    
    ## 4. Find out whether the process is worth its cost
    
    Let me link a change to an incident from either side, with a relationship
    type: caused, contributed to, or discovered during.
    
    Then report change-related incident rate: the proportion of changes
    followed by a linked incident, broken down by type, risk level and system.
    Plus rollback rate, failed change rate, and time from request to approval
    by risk level, since slow approval is the leading cause of an incomplete
    log.
    
    Build the audit export: every change in a period with its classification,
    its approvals and timestamps, its outcome, and any linked incidents. One
    click, because that is what the log is for.
    
    And flag any change type classified as standard that has a higher incident
    rate than normal changes. Those are misclassified, and the data will tell
    you before an auditor does.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <GitHub>. Read what actually shipped and when, so a standard change is one
    confirmation rather than a form.
    
    <Jira>. Link a change to the work behind it and to any incident that
    followed.
    
    <Datadog>. Correlate changes with incidents, which is how you find a
    misclassified standard change.
    
    <Slack>. Route approvals for the changes that genuinely need one, and
    reroute to a deputy.
    
    <ServiceNow>. If change management already lives here, read and write
    there rather than running two logs.
    
    <LaunchDarkly>. Read flag changes, which are changes to production whether
    or not anybody filed one.
    
    <Okta>. Attribute every filing, approval and skip to a verified person,
    which is what makes it evidence.
    
    <Snowflake>. Join the change log to the incident record, which is what
    makes change-related failure rate a number rather than an argument.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  38. IT and Operations

    internal admin dashboard

    Let support answer account questions and fix common problems themselves, through named actions against production data, with every action logged. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Find the record, then see all of it
    
    In this Helix project, build me an internal admin dashboard for our support
    team.
    
    Start with search. One box that matches on the identifiers an enquiry
    actually arrives with: email address, account name, customer id, order or
    invoice number, phone number, support ticket reference. Partial matches on
    names and emails, exact on identifiers.
    
    Show enough in the results to tell two candidates apart: name, email,
    status, created date, plan. Support very often has two and needs to pick.
    
    Then a record page that assembles everything about one customer in one
    place: profile, plan and billing status, recent orders or transactions,
    recent activity, open tickets, and any flags.
    
    Pull each section from its own module, and render a section that fails to
    load as unavailable with a retry rather than failing the whole page. One
    slow system should not make the dashboard useless, and a partial outage is
    exactly when support needs it most. Show the last refresh time per
    section.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Actions, never a field editor
    
    Now the important part. Define every operation as a named action rather than
    exposing raw field editing.
    
    For each one specify: a name, what it does, the preconditions, the role
    required, whether a reason is mandatory, and whether it is reversible.
    
    Start with these and let me add more in a config file: send a sign-in link
    or reset a password, extend a trial by a set number of days, apply a
    credit or refund up to a role-dependent limit, resend a receipt or
    notification, cancel or reschedule an order, merge duplicate records,
    suspend or reinstate an account, add an internal note.
    
    Rules for all of them. Show a preview of what will change before it
    happens. Require a typed confirmation for anything destructive or
    irreversible. Enforce the role server side, not just by hiding a button.
    And refuse cleanly rather than partially applying when a precondition
    fails.
    
    Do not build a generic field editor. If an agent needs to change something
    not on this list, that should become a new named action.
    
    ## 3. The audit log, visible where it helps
    
    Add an append-only audit log: actor, action, target record, timestamp,
    reason, parameters, a before and after snapshot, and the outcome. Never
    edited, never deleted.
    
    Log every action including failed attempts and refusals. A blocked attempt
    is frequently the more interesting entry.
    
    If the data warrants it, log views of sensitive records too, as a separate
    lower-volume entry type.
    
    Make the audit searchable by actor, action, target and date range, and put
    it on the record page itself so an agent can see what was already done to
    this account before acting. Most confusing account states turn out to be
    something a colleague did last week.
    
    Then report actions per operator per week, the most used actions, and
    refusals by reason. A frequently refused action is usually a precondition
    that does not match reality.
    
    ## 4. Make the blast radius small on purpose
    
    Put roles in a config file, each listing the actions it may perform and any
    limits such as a maximum refund. Enforce server side.
    
    Include a read-only role. It will cover most requests for access, because
    most people asking for an admin dashboard only need to look something up,
    and giving them a role that cannot change anything removes most of the
    risk of saying yes.
    
    Rate limit each action per operator, so a mistake or a compromised account
    cannot touch a thousand records before anyone notices.
    
    Give bulk actions their own path: a higher role, the full list of affected
    records shown first, a typed confirmation, and one audit entry per record
    rather than one for the batch.
    
    If I ask for a view-as feature, make it strictly read-only, time limited,
    loudly indicated in the interface throughout, and audited on entry and
    exit.
    
    And add a test mode against sample data so new agents can learn the tool
    without touching a real account.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <your product database>. Read the customer record and perform the named
    actions. Scope this to the actions you defined, not to everything.
    
    <Stripe>. Read plan and payment status, and apply the credits and refunds
    your roles allow.
    
    <Zendesk>. Show open tickets on the record, so support is not holding two
    tabs.
    
    <Okta>. Authenticate the operator and read their group, so every action in
    the audit log has a verified name and a role behind it.
    
    <Salesforce>. Show the account and its owner, so an agent knows who to
    hand a commercial question to.
    
    <Snowflake>. Read usage history for the account, which the production
    database should not be queried for.
    
    <Slack>. Post high-privilege actions to a channel security can watch, in
    addition to the audit log.
    
    <Gmail>. Resend receipts and notifications, which is a large share of what
    support is asked for.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  39. IT and Operations

    inventory tracker

    Track what you hold by movements rather than a quantity field, reconcile against a physical count, and reorder before you run out. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Items, and movements as a ledger
    
    In this Helix project, build me an inventory tracker.
    
    Two tables, and the second one is the important one.
    
    Items: a code, a name, a description, a unit of measure, a category, a
    default location, a supplier, a unit cost, and whether the item is
    active.
    
    Movements: an append-only ledger. Item, quantity, a type from a fixed
    list (received, issued, transferred, returned, adjusted, written off),
    the location it moved from and to, a reason, who did it, and when.
    
    Derive the stock level from the movements. Never store a quantity field
    that somebody can edit. The moment two people can change the same number,
    the record stops being able to explain itself, and the question you will
    actually be asked is where the missing four went.
    
    Require a reason on every adjustment and write-off. An adjustment of
    minus four with no reason attached is how people stop believing the
    system.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Locations, and what counts as in stock
    
    Add locations, and make them real rather than a text field.
    
    A location has a name, a type (warehouse, stockroom, van, desk, in
    transit, with a customer), and optionally a parent, so a bin sits inside
    a stockroom inside a site.
    
    Stock is now per item per location, still derived from movements. A
    transfer is one movement out and one movement in, recorded together so
    the ledger balances.
    
    Then define available separately from on hand. On hand is everything
    physically present. Available excludes anything reserved, in transit, or
    already allocated to something. Show both, because the gap between them
    is what causes somebody to promise stock that is already spoken for.
    
    Let me allocate stock to a job, an order or a person, and have that
    allocation reduce available without touching on hand.
    
    ## 3. Reconcile, and keep the variance
    
    Add reconciliation.
    
    Let me start a count for a location or a category, list the items to
    count, and enter what was physically found. Show the derived figure only
    after the counter has entered theirs, so the count is not anchored by the
    system.
    
    Where they differ, record the variance as its own adjustment movement,
    with the count as the reason. Do not quietly overwrite the number.
    
    Then report variance over time by item, by location and by person doing
    the counting. Persistent variance on one item is usually a unit of
    measure problem. Persistent variance in one location is usually a process
    problem. Persistent variance under one counter is a third thing, and you
    want to be able to tell them apart.
    
    Let me schedule counts so high-value or fast-moving items are counted
    more often than everything else, rather than one enormous annual count
    nobody enjoys.
    
    ## 4. Reorder before you run out
    
    Add reorder points, and build the lead time into them.
    
    For each item: a minimum level, a reorder quantity, and the supplier lead
    time in days. Calculate the reorder point from average consumption over a
    period multiplied by the lead time, plus a buffer I set, rather than
    asking me to guess a number.
    
    Reordering when stock hits zero means being out for however long delivery
    takes, which is the failure this is meant to prevent.
    
    Flag items below their reorder point, ranked by how many days of cover
    remain rather than by how low the number is. Two units of something you
    use twice a year is not urgent; two units of something you use daily is.
    
    Then report consumption trends per item, items that have not moved at all
    for a period, which is capital sitting on a shelf, and stock value by
    location for the finance conversation.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Read purchase orders so a receipt can be matched to what was
    ordered, and push the stock valuation back.
    
    <Coupa>. Raise the reorder as a real purchase request rather than an email
    to a supplier.
    
    <Okta>. Read each person's location attribute, which is what the app uses
    to default a movement to their own site.
    
    <Slack>. Warn the owner when an item drops below its reorder point, ranked
    by days of cover.
    
    <Google Sheets>. Take the opening count as counted, since the first stock
    list is always somebody walking the shelves with a sheet.
    
    <Snowflake>. Land every movement, so consumption per site across a season
    can be modelled rather than eyeballed from one month.
    
    <Jamf>. For an IT stockroom, reconcile issued devices against what device
    management can actually see.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  40. IT and Operations

    field inspection app

    Capture an inspection on a phone, offline, with photos attached, and route the failures to somebody who can fix them before anyone leaves site. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A checklist somebody can use with one thumb
    
    In this Helix project, build me a field inspection app. It will be used on
    a phone, outdoors or in a plant room, sometimes in gloves.
    
    Templates: an inspection type with an ordered list of items, each with a
    description, a response type (pass or fail, a reading with a unit, a
    choice from a list, or a count), whether it is mandatory, and whether a
    photo is required when it fails.
    
    Inspections: the template used, the location, the asset if there is one,
    the inspector, the start and finish time, and a response per item.
    
    Design the capture screen for a phone first and a desk second. Large tap
    targets, one item at a time or a short scrollable list, pass as the
    default so the inspector only interacts with exceptions, and as little
    free text as possible.
    
    Capture the timestamp and location automatically. An inspection record
    that depends on somebody typing the date is a record you cannot rely on.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Make it work with no signal
    
    Now make the whole thing work offline, because this is the part that decides
    whether the app survives.
    
    An inspector must be able to open a template, complete every item, attach
    photos and finish an inspection with no connection at all, then have it
    sync when they get signal.
    
    Show the sync state clearly on the device: how many inspections are held
    locally, when the last sync happened, and whether anything failed to
    upload. Somebody standing in a car park needs to know their morning's
    work is safe before they drive away.
    
    Handle photos properly, because they are the thing that breaks this.
    Compress on the device, queue them separately from the inspection record
    so a slow photo upload does not block the data, and retry.
    
    Never lose an inspection to a failed sync. Keep it locally until upload
    is confirmed, and make a stuck one obvious rather than silent.
    
    ## 3. Evidence attached to the item that failed
    
    Attach evidence per item rather than per inspection.
    
    When an item fails: require a photo if the template says so, allow a
    note, and record the reading if there is one. Keep all of that against
    that item.
    
    A gallery of twelve photos at the bottom of an inspection with no
    indication of which item each belongs to is not evidence, and it is what
    almost every paper process produces.
    
    Let the inspector annotate a photo with a mark or an arrow, because
    "the crack is on the left-hand bracket" is much clearer drawn than
    written on a phone.
    
    Show the previous inspection's result for the same item while they are
    looking at it. An inspector who can see that this item also failed last
    month reports it differently.
    
    ## 4. Route the failure before they leave site
    
    Add the exception path, and make it fire on completion rather than after
    somebody reviews the paperwork.
    
    Each failed item raises a job: what failed, where, the evidence, a
    severity from the template, an owner routed by severity and location, and
    a due date derived from the severity.
    
    Critical failures notify immediately. Everything else lands in the
    owner's queue.
    
    Track each job to closure with evidence of the fix, and show it on the
    next inspection of that item, so an inspector can see whether the thing
    they raised last time was ever done.
    
    Then report: completion rate against schedule, items that fail most
    often, locations that fail most often, average time to close a job by
    severity, and repeat failures at the same location. That last one is the
    finding. One failed item is a job; the same item failing every month is a
    different problem and nobody sees it from individual inspections.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Okta>. Identify the inspector, because an inspection is only evidence if
    you know who did it.
    
    <Jamf>. Push the app's url to managed phones as a web clip, and confirm
    the device doing the inspection is one of yours.
    
    <Jira>. Raise the job from a failed item into the queue the maintenance
    team already works from.
    
    <Slack>. Notify immediately on a critical failure, rather than waiting for
    the inspection to be reviewed.
    
    <Google Drive>. Store photos and signed inspection records where retention
    rules already apply.
    
    <NetSuite>. Read the asset register so an inspection is against a real
    asset rather than a typed location.
    
    <Snowflake>. Push inspection history into the warehouse, which is how
    repeat failures across locations become visible.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  41. IT and Operations

    internal helpdesk

    One front door for internal requests, a form per request type that collects what the fixer needs, routing that does not depend on who was asked, and a queue you can staff from. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. One front door, with a form per request type
    
    In this Helix project, build me an internal helpdesk.
    
    A request record: requester, request type, description, priority, status,
    assigned team, assigned person, created and resolved timestamps, and the
    conversation history.
    
    Then a form per request type, and this is the part that matters. Do not
    give me one description box.
    
    An access request asks which system, which access level, for how long,
    and the business reason. A hardware fault asks the asset tag, what
    happens and when it started. A new starter asks the start date, the role,
    the manager and which systems they need.
    
    Every field a form asks for is a question the fixer does not have to ask
    later. A generic box means the first reply is always "which system?",
    and that round trip is most of the time the ticket takes.
    
    Let me add and edit request types without a redeploy, because the list
    changes constantly and it is the thing everyone else wants to change.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Route on the type, not on who was asked
    
    Now route on the request type rather than on who received the message.
    
    Each type maps to a team, and each team has members and a rota. Assignment
    goes to the team first, then to a person, so nothing sits in a queue with
    no owner and nothing lands in a leaver's name.
    
    Derive priority from two things the requester does not choose: impact,
    meaning how many people are affected and whether they are blocked, and
    urgency, meaning whether there is a deadline. Let me set the matrix.
    
    Do not let the requester pick the priority. Given the option everything
    is high, which is the same as nothing being high, and then the real
    outage is in a queue behind a printer.
    
    Add deflection at intake. When somebody starts a request, search existing
    documentation and recently resolved requests, and show the likely answer
    before they submit. If the answer already exists in writing, showing it is
    cheaper than paying a person to paste the link.
    
    Track how often deflection worked. That is the number that decides
    whether the documentation is worth writing.
    
    ## 3. A queue people can actually work from
    
    Build the working view, and design it for the person clearing the queue
    rather than the person reporting on it.
    
    Their own assigned requests first, then their team's unassigned, sorted
    by priority and by how close each is to breaching its target.
    
    Every request shows the requester, what they asked, everything the form
    collected, and the history in one place. No tab switching to answer a
    question.
    
    Common actions in one click: reply, reassign, ask the requester for
    something and pause the clock, resolve with a note.
    
    Set response and resolution targets by priority, and show a countdown
    while it can still be met rather than a breach report afterwards. Pause
    the clock when you are waiting on the requester, and count that time
    separately, because a queue that punishes a team for a requester's
    holiday gets gamed within a fortnight.
    
    Give it a search that covers resolved requests too. Half of helpdesk work
    is finding how this was fixed last time.
    
    ## 4. Report on repeats, not just throughput
    
    Last, the reporting, and lead with the thing that reduces volume rather
    than the thing that measures speed.
    
    Group requests by what they were actually about and show the most
    frequent. Ten access requests a week for the same system is a
    provisioning problem, not a helpdesk problem, and it is invisible when
    you only count resolution time.
    
    Then show volume by type and team over time, time to first response and
    to resolution by priority, the proportion breaching target, deflection
    rate, and reopened requests. Reopened is the honest quality measure,
    because it counts the ones marked resolved that were not.
    
    Show volume by requesting team as well. One department generating four
    times its share usually means something is broken upstream that nobody
    has connected to the ticket count.
    
    A helpdesk that only gets faster is still answering the same question
    forever. The repeats report is the one that changes anything.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Slack>. Raise a request from where people already ask, and reply in the
    thread. This is the single biggest determinant of whether anyone uses it.
    
    <Okta>. Identify the requester, read their team and manager so the form
    does not ask, and provision the access a request approves.
    
    <Gmail>. Accept requests by email and reply from the ticket, because some
    people will never use a form.
    
    <Jira>. Escalate a request that turns out to be a bug or a change, with
    the history attached rather than retyped.
    
    <Notion>. Search the internal documentation at intake, which is what makes
    deflection work rather than being a nice idea.
    
    <Workday>. Read the joiner and leaver feed, so onboarding requests arrive
    before somebody remembers to raise one.
    
    <Jamf>. Read device state for a hardware request, so the fixer can see the
    machine rather than ask about it.
    
    <Snowflake>. Push resolved requests into the warehouse, which is how
    repeat analysis across a year becomes a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  42. Legal and Compliance

    legal contract intake queue

    One front door for legal work, with enough detail captured up front to triage it, a queue with priorities, and self-service for the requests that do not need a lawyer. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A front door that captures enough to start
    
    In this Helix project, build me a legal contract intake queue.
    
    One request record: requester and team, request type, counterparty name
    and type, contract value, currency, deadline, the reason for that
    deadline, business context, whether a template was used, the related
    opportunity, and any documents.
    
    Request types to seed: new agreement, review counterparty paper, renewal,
    amendment, termination, NDA, data processing agreement, general question.
    
    Make the form adapt to the type. An NDA needs far less than a master
    services agreement, and asking for everything every time trains people to
    submit nothing useful.
    
    Require the counterparty, the value and the deadline on every request.
    Each missing field is a round trip that costs a day.
    
    Then a triage step that sets risk, priority, owner and target date.
    Suggest a priority derived from deadline and value, and let the triager
    override it with a reason. Prioritising by who asked means the loudest
    requester sets the queue and the highest-risk contract waits behind a
    routine NDA.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Show the team what it is carrying
    
    Build the queue: open requests sorted by priority then deadline, showing
    type, counterparty, value, requester, owner, age and days to deadline.
    
    Add a per-owner workload view split by type and risk, so assignment is
    based on capacity rather than on who replied first.
    
    Let me edit the status list, and cover the states that actually happen:
    received, triaged, in review, with counterparty, awaiting business input,
    awaiting signature, completed, withdrawn.
    
    Then track time in each status and report awaiting business input
    separately from everything else. A large part of what gets called legal
    delay is a request sitting with the person who raised it, and until that
    is visible legal wears the blame for it.
    
    Flag requests past their target date, and requests approaching a deadline
    with no owner.
    
    ## 3. Remove the requests that never needed a lawyer
    
    Now the part that gives the team its capacity back.
    
    Keep templates as records: name, type, when to use it, when not to, the
    approved version, a document link, an owner, and a last reviewed date.
    
    Build a guided path for standard requests. The requester answers a few
    questions, and if the answers stay inside the guardrails, generate the
    agreement from the approved template and record that it was used, by whom,
    with which counterparty, on what date.
    
    Any answer outside the guardrails routes into the normal queue with the
    answers already captured.
    
    Then track two numbers: how many requests were handled without a lawyer,
    and how many escalated afterwards because the counterparty asked for
    changes. The second tells me whether the guardrails are set correctly.
    
    And flag templates not reviewed within a period I set.
    
    ## 4. What happens after signature
    
    Keep executed agreements: counterparty, type, effective date, term end,
    notice period, auto renew, value, signatory, document link, and the
    request it came from. Derive a notice deadline and sort by that rather
    than term end.
    
    Then obligations: what we committed to, an owner, a due date, whether it
    recurs, and a status. Report by owner and flag overdue ones. This is the
    part everybody means to do and nobody does.
    
    Finally, report requests by type, team and month; turnaround by type with
    the waiting-on-the-business time excluded and shown separately;
    self-service share; and the counterparties we contract with most often,
    which is usually where negotiating a standard form once pays for itself
    many times.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Read the opportunity behind a contract request, which is
    where the value and deadline come from.
    
    <Google Drive>. Keep drafts and executed agreements where the business
    already looks for them.
    
    <DocuSign>. Read signature status, so awaiting signature is a real state
    rather than a guess.
    
    <Slack>. Accept requests from wherever people send them, because they will
    not all use the form.
    
    <Okta>. Tell the app who is signing in and whether they are in the legal
    group, which is what its visibility rules run on.
    
    <Ironclad>. If contract lifecycle already lives somewhere, read and write
    there rather than running a second system.
    
    <NetSuite>. Read the spend behind a contract request, which is usually
    what sets its priority.
    
    <Google Sheets>. Export the obligations register, because whoever owns an
    obligation will want it in a sheet.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  43. Legal and Compliance

    policy attestation tracker

    Version your policies, assign them to the right people, collect attestations with evidence, and produce the completion report an audit asks for. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Versions, because that is what makes it evidence
    
    In this Helix project, build me a policy attestation tracker.
    
    Policies have versions, and versions are never edited. Each version has a
    number, an effective date, the document, a summary of what changed from
    the previous one, who published it and when.
    
    Add a flag per version saying whether it requires everyone to re-attest,
    or only people who have never attested. That flag is what keeps this
    proportionate. A typo correction should not send four hundred people back
    to a document, and forcing it destroys engagement with the ones that
    matter.
    
    Show the summary of changes to anyone re-attesting. People deserve to know
    what is different, and a written summary field is enough.
    
    Flag policies past their review date, and any version with no effective
    date set.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Assign by rule, continuously
    
    Now assignment. Write rules over person attributes: department, role, level,
    location, employment type. Each rule says which policy applies and how
    many days somebody has, counted from the later of the version's effective
    date and that person's start date.
    
    Evaluate those rules continuously rather than at publish time. A new
    joiner picks up every policy they need, and someone changing role picks up
    the new ones. A one-off assignment list is stale the day after it is
    generated, and joiners and movers are exactly the people most likely to be
    missed.
    
    Let me see, per version, the current assigned population and how it was
    derived, so I can check a rule before publishing.
    
    And handle leavers: their outstanding attestations close as not applicable
    rather than sitting overdue forever and quietly ruining the report.
    
    ## 3. Collect it in a way that holds up
    
    An attestation records the person, the exact policy version, the timestamp,
    the method, and the statement text they accepted. Immutable once created.
    
    The page shows the policy, requires the person to reach the end before the
    accept action is enabled, and states plainly what they are attesting to.
    
    Support optional comprehension questions per version, configurable, with
    answers recorded. Use them for the few policies where it matters rather
    than everywhere.
    
    Notify on assignment, remind on a schedule before the due date, then
    notify the person's manager once it passes.
    
    Give everyone a personal view of what they owe, what is outstanding, and
    what they have already accepted with the version and date.
    
    And do not allow an attestation to be made on somebody's behalf. If a
    paper process is genuinely needed, record it as a separate evidence type
    with the document attached and a note of who recorded it.
    
    ## 4. The reports that are the reason to build it
    
    Report completion by policy, version, department and manager, and always
    separate three states: completed, outstanding but not yet due, and
    overdue. Collapsing the last two into one outstanding figure makes the
    completion percentage meaningless the week after a policy is published.
    
    Give managers a view of their own team's outstanding items.
    
    Report time to attest, as a median and a distribution per version. A
    policy that takes six weeks to reach ninety percent has a distribution
    problem rather than a compliance one, and that is a different fix.
    
    Then the export: every person in scope for a period, the policy version,
    the attestation timestamp, and the statement accepted. One click, as a
    file an auditor can read without explanation.
    
    Plus an exceptions view of people who have never attested to something
    assigned to them, and a per-person history of every version they have ever
    accepted, which is what gets requested when one individual becomes the
    subject of a question.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Workday>. Read department, role, level, location and start date,
    evaluated continuously so joiners are never missed.
    
    <Okta>. Authenticate every attestation, which is what makes the record
    evidence rather than a claim.
    
    <Google Drive>. Hold each policy version, so an attestation points at
    exactly what was accepted.
    
    <Slack>. Remind before the due date and escalate to a manager after it.
    
    <Vanta>. Push completion evidence in as it happens, so nobody exports the
    same attestation record twice.
    
    <Gmail>. Send the attestation request and the reminders, timestamped
    against the due date.
    
    <Snowflake>. Keep the historical record queryable, so a per-person history
    survives a policy being retired.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  44. Legal and Compliance

    vendor security review tracker

    Tier vendors by the risk they actually carry, ask each tier only what it warrants, track findings to closure, and re-review on a schedule. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Tier on risk, not on spend
    
    In this Helix project, build me a vendor security review tracker.
    
    Start with intake and triage. Capture the vendor, the requesting team, the
    business owner, what the tool is for, expected users and annual cost.
    
    Then ask the requester a short set of questions: what data will this
    vendor access, does it include personal data, does it include customer
    data, will it integrate with core systems, is it in the path of a
    customer-facing process, and what happens if it is unavailable for a day.
    
    Derive the risk tier from those answers rather than asking anybody to
    choose one. And tier on data access and criticality, never on contract
    value. A cheap tool holding customer records carries far more risk than an
    expensive one holding none.
    
    Show the derived tier at the point of request, along with what it means
    and the expected turnaround. A requester who can see that a low-tier tool
    clears in three days stops looking for a way round the process.
    
    And flag vendors we have already reviewed, so the second team asking for
    the same tool sees the existing record instead of starting again.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Ask each tier only what it warrants
    
    Put question sets per tier in a config file, with the evidence requested
    and whether each item is mandatory.
    
    Low tier: a short set on authentication, data location and incident
    notification. High tier adds a current audit report, a penetration test
    summary, a subprocessor list, a data flow description, breach history and
    business continuity.
    
    Then the single biggest reduction in review time available: let me mark
    questions as answered by evidence when a current certification or audit
    report already covers them. Re-asking what a report answers wastes
    everybody's time and slows down nothing except you.
    
    Give vendors a link so they can answer directly and upload evidence
    without needing an account in our systems.
    
    And track document expiry. An audit report from three years ago is not
    current, and the app should say so rather than showing a green tick.
    
    ## 3. Findings, and the decision you actually made
    
    Findings are their own records: description, severity, category, an owner
    who might be the vendor or somebody internal, a remediation plan, a due
    date, a status, and evidence of closure.
    
    Accepted risks are findings too, with a status of accepted, an approver, a
    reason, and an expiry date. A risk accepted with no expiry is a permanent
    decision made by whoever happened to be in the room, and nobody ever
    revisits it.
    
    The review decision is approved, approved with conditions, rejected or
    pending, with each condition linked to the finding it came from.
    Conditional approvals need a check before the condition's due date,
    assigned to the internal business owner rather than to security.
    
    Then a review record per vendor per cycle: who reviewed, when, what
    evidence they saw, the findings, and the decision. That is the artefact an
    auditor or a customer questionnaire asks for.
    
    ## 4. Re-review, and the register your own customers will ask for
    
    Set a re-review cadence per tier, say annually for high tier and every
    three years for low, with the next date derived and visible.
    
    Then let me record a trigger that pulls a re-review forward: a reported
    breach, a change of subprocessor, an acquisition, an expiring audit
    report, or a change in what the vendor accesses. Recording any of those
    reschedules it automatically.
    
    Report vendors by tier, open findings by severity and age, accepted risks
    approaching expiry, reviews overdue, and average time to complete a review
    by tier. That last one tells me whether the tiering is actually saving
    anything.
    
    And build a vendor register export: every vendor, tier, data accessed,
    review date and decision. Your own customers will ask for this during
    their security review of you, and having it ready turns a week into an
    hour.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Google Drive>. Hold audit reports, penetration test summaries and
    subprocessor lists, with their expiry dates.
    
    <NetSuite>. Read spend and contract terms, and catch the vendor a second
    team already bought.
    
    <Gmail>. Send the questionnaire to the vendor and take answers back
    without giving them an account.
    
    <Okta>. Resolve internal reviewers and business owners to real accounts,
    and flag a conditional approval whose owner has left.
    
    <Vanta>. Read your own posture and push the vendor register into the same
    place your customers ask about.
    
    <Coupa>. Catch the vendor a second team already bought, before reviewing
    it twice.
    
    <Slack>. Tell a requester their tier and expected turnaround at the moment
    they ask.
    
    <DocuSign>. Read whether the data processing agreement was actually
    signed, not just drafted.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  45. Legal and Compliance

    data subject request tracker

    Log every request the day it arrives, verify who is asking, work a system inventory rather than a memory, and evidence what you did before the deadline. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. The clock starts when it arrives
    
    In this Helix project, build me a data subject request tracker.
    
    A request records: the subject's name and contact details, the date it
    arrived, the channel it arrived through, the request type, what they
    actually asked for in their own words, and who received it.
    
    Request types to seed: access, deletion, rectification, portability,
    restriction, objection, and a general question. Let me edit that list.
    
    Now the important part. Derive the statutory deadline from the arrival
    date and a period I configure per request type, and treat that derived
    date as the thing the whole app is organised around. The clock starts when
    the request arrives, not when somebody gets round to logging it, so let me
    backdate the arrival date and have everything recalculate.
    
    Support extending the deadline where the law allows it, with the reason
    and the notification to the subject recorded, because an extension that
    was never communicated is not an extension.
    
    And accept requests from any channel. People send these by replying to a
    marketing email or mentioning it in a support ticket, and an intake that
    only accepts a form will miss those entirely.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Verify before you disclose
    
    Add identity verification as a required step before any data can be
    disclosed.
    
    Record what was checked, by whom, and when. Let me define what is
    proportionate per request type: confirming a signed-in account may be
    enough for one thing, and a deletion request from an unverified email
    address needs more.
    
    Do not let the workflow reach a disclosure state until verification is
    recorded. Sending one person's data to somebody impersonating them is a
    breach caused by trying to be compliant, and it is a well-documented
    attack rather than a hypothetical one.
    
    Handle requests made on somebody's behalf: a parent, a solicitor, an
    authorised agent. Those need evidence of authority recorded as well as
    identity, and they are the ones most likely to be got wrong.
    
    Track the clock through verification. Time spent waiting for the subject
    to verify usually does not count against you, but only if you recorded
    when you asked.
    
    ## 3. Search a list, not your memory
    
    Build a system inventory, and make the search work against it.
    
    Each system records: name, what categories of personal data it holds, a
    named owner, how a search is performed there, whether deletion is possible
    and what it means in that system, and any retention rule that overrides a
    deletion request.
    
    When a request is opened, generate a search task per relevant system,
    assigned to that system's owner. Each task records what was searched for,
    what was found, and what was done, or that nothing was found.
    
    A request cannot be completed until every task is answered. Searching from
    memory guarantees a system gets missed, and the missed system is always
    the one nobody thinks of, like the backup, the analytics tool, or the
    spreadsheet on somebody's laptop.
    
    Flag any system in the inventory with no owner, and any system not
    reviewed within a period I set. An inventory that has gone stale is worse
    than an obviously incomplete one, because people trust it.
    
    ## 4. Evidence, and the deadline you can see coming
    
    Record the response: what was disclosed, in what format, when, and to whom.
    Record what was withheld and the specific exemption relied on. Withholding
    something without a stated basis is the finding, not the withholding.
    
    Keep the outbound package itself, so what was actually sent is preserved
    rather than reconstructed.
    
    Then the views. A dashboard ordered by days remaining, not by date
    received, with anything inside a threshold I set highlighted and anything
    overdue at the top and impossible to miss. Notify the owner and their
    manager as the deadline approaches.
    
    And reporting: requests by type and month, median days to complete, how
    often each exemption was relied on, which systems take longest to search,
    and any request completed after its deadline with the reason. That last
    list should be empty, and if it is not, it is the first thing to fix.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <every system in your inventory>. Search for the individual and record
    what was found, or that nothing was. This is the work.
    
    <Okta>. Authenticate the people handling requests and read the group that
    says who is allowed to. This is personal data about identified
    individuals, so the app should trust the group and nothing else.
    
    <Google Drive>. Hold the response package, so what was sent is preserved
    rather than reconstructed.
    
    <Gmail>. Acknowledge the request and deliver the response, both
    timestamped against the statutory clock.
    
    <OneTrust>. If privacy operations already run somewhere, read requests
    from there rather than running a second intake.
    
    <Salesforce>. Search the CRM, which is almost always the largest single
    store of personal data.
    
    <Zendesk>. Search support history, which is where the most sensitive free
    text usually is.
    
    <Amplitude>. Search analytics, which is the system people forget holds
    anything identifying.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  46. Marketing

    campaign brief intake app

    Capture enough in a brief to start work without a meeting, prioritise against capacity rather than volume, and show requesters where their work sits. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. A brief you can start from
    
    In this Helix project, build me a campaign brief intake app.
    
    Capture the requester and team, the request type, the objective, a
    measurable target, the audience, the key message, the channels, the
    deliverables, the deadline, the reason for that deadline, the budget, and
    any dependencies.
    
    Adapt the fields to the request type. A landing page needs the conversion
    goal and where it points. An event needs dates, audience size and the
    session detail. One long form for everything produces short answers on
    every field.
    
    Then two rules that do most of the work.
    
    Require an objective and a measurable target, and reject a brief where the
    objective just restates the deliverable. Say why. "We need a landing page"
    is a deliverable. "300 qualified sign-ups by the end of Q3" is an
    objective, and it produces different work from the same team.
    
    And require a written reason for the deadline. Most deadlines are
    preferences, and it is surprisingly hard to write a justification for a
    date you made up.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. A queue order you can defend
    
    Score each brief on strategic fit, expected impact, effort and deadline
    pressure, each weighted, from a config file I can edit. Show the
    components as well as the total, so a score can be argued with
    specifically rather than dismissed generally. Effort is estimated by the
    delivery team, not by the requester.
    
    Then build a capacity model: who is on the team, their available hours per
    week by discipline, and their current commitments. Rank the queue by score
    and draw a line where capacity runs out.
    
    Show what is above and below that line explicitly. A queue with no
    capacity model just re-sorts a list that is longer than the team can
    deliver, and everybody stays disappointed for a different reason.
    
    Let a leader override the order with a reason, and log every override. The
    overrides list is the most honest description of a company's real
    priorities that exists anywhere.
    
    ## 3. Remove the chasing
    
    Build the team queue: in progress, scheduled, and backlog, with owner,
    score, deadline and status.
    
    Then the requester's view: their own briefs, their position in the queue,
    status, expected start and expected delivery. Most escalation comes from
    not knowing where something sits rather than from genuine urgency, so this
    reduces interruptions more than it increases arguments.
    
    Let me edit the status list, and include "needs more information", which
    returns the brief to the requester with the specific gaps named and pauses
    its clock.
    
    Track time in each status, and report time waiting on the requester
    separately from time with the team.
    
    Support dependencies between briefs, so a launch needing three pieces
    shows as blocked on the slowest one.
    
    ## 4. Close the loop, or next quarter is the same argument
    
    On delivery, record what shipped with links, the date, and the actual effort
    against the estimate.
    
    Then record results against the objective in the brief: the metric, the
    target, the actual, and when it was measured. Prompt for it a configurable
    period after delivery, because nobody comes back on their own.
    
    Report briefs by type, team and quarter. Delivered against requested.
    Estimate accuracy by discipline. Time from submission to delivery, split
    into time with the team and time waiting. And results against target where
    they were recorded.
    
    Rank requesting teams by volume and by results, which is a conversation
    worth having once a quarter with the data present.
    
    And flag briefs delivered with no result recorded past the prompt period.
    A large number there means the objectives were never real, which is itself
    the finding.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Asana>. Read current commitments to build the capacity model, and push
    scheduled briefs into it.
    
    <Okta>. Resolve requesters and their teams from the directory, so a brief
    is attributed to a real person without anybody maintaining a list.
    
    <Google Analytics>. Pull results against the objective, which is what
    makes next quarter a different argument.
    
    <Slack>. Tell a requester where their brief sits, which removes most of
    the escalation.
    
    <Marketo>. Read what actually shipped and what it produced, so results are
    not self-reported.
    
    <Google Drive>. Hold the assets and the brief together, rather than a link
    to a link.
    
    <Snowflake>. Read pipeline attributed to each campaign, which is the only
    honest result field.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  47. Marketing

    marketing budget tracker

    Track committed spend alongside invoiced spend by programme, so a channel owner knows what they have left before they commit it. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Structure it the way marketers decide
    
    In this Helix project, build me a marketing budget tracker.
    
    Structure the budget by programme rather than only by cost centre:
    programme name, channel, type, owner, quarter, planned spend, currency and
    objective. Cost centres are a finance structure, and marketers make
    decisions at the programme level, so a tracker organised the other way
    cannot answer the questions they ask.
    
    Channels to seed: paid search, paid social, events, content, sponsorship,
    agency and freelance, tools, brand.
    
    Keep budget versions so a reforecast never overwrites the original plan.
    The gap between them is its own report.
    
    Then commitments, recorded at signature rather than at invoice: programme,
    vendor, description, amount, currency, signed date, contract reference,
    and the expected invoice schedule as one or more dated lines. That gap
    between signing and invoicing is the entire disagreement between marketing
    and finance.
    
    Two things to build in now rather than retrofit: commitments that span
    quarters, split across the periods their invoices land in, and
    multi-currency, storing the original amount and a converted amount at a
    rate I set per period.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Agree with finance instead of arguing with them
    
    Import actuals from finance on a schedule: programme, vendor, amount,
    currency, invoice reference and dates, cost centre, description. Record
    the last successful import and show it on every page, and say so on screen
    when one fails rather than serving stale numbers quietly.
    
    Match each actual to an open commitment by vendor, amount and expected
    date, within a tolerance I configure. A matched actual reduces the open
    commitment rather than adding to the total.
    
    Then surface two unmatched views, both directions. Actuals with no
    commitment, which is spend that bypassed the process. And commitments long
    past their expected invoice date, which are either late invoices or work
    that stopped without anyone telling finance.
    
    And show planned, committed, actual and remaining together everywhere.
    Never a single remaining figure on its own.
    
    ## 3. The screen that prevents overspend
    
    Build the owner view: their programmes, with planned, committed, actual,
    remaining, and the percentage consumed. Then roll up by channel, by
    quarter, and for the year.
    
    Alert an owner when a programme crosses thresholds I set, and again when
    committed plus actual exceeds the plan.
    
    Then build the pre-commitment check, and make it easy to find. Enter a
    proposed amount against a programme and see what would remain if it were
    signed. This is the screen people will use most, and it is the only one
    here that stops an overspend rather than describing one afterwards.
    
    Highlight programmes with a lot of unspent budget late in a quarter, which
    is a planning signal as much as a spending one.
    
    And let me transfer budget between programmes, with an approver, a reason,
    and a full history.
    
    ## 4. Whether to spend it again
    
    Record results per programme: the metric, the target, the actual, when it
    was measured and where it came from.
    
    Derive cost per outcome, and restrict comparisons to within a channel.
    Comparing an event to paid search on cost per lead reliably produces the
    wrong decision, because the two produce different kinds of pipeline that
    convert differently.
    
    Add a quarter-close snapshot that freezes the figures, so a later
    correction does not change a number already reported to a board.
    
    Then report spend by channel against plan, committed versus invoiced over
    time, cost per outcome trend per programme, and the budget transfer history
    with reasons. Plus one summary line I can paste into a monthly update:
    planned, committed, invoiced, remaining, and the largest variance with its
    owner.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <NetSuite>. Import posted actuals on a schedule and reconcile them against
    open commitments.
    
    <Coupa>. Read signed orders, so a commitment is recorded at signature
    rather than at invoice.
    
    <Google Analytics>. Pull results per programme, so cost per outcome is
    derived rather than estimated.
    
    <Slack>. Warn an owner when committed plus invoiced crosses the plan.
    
    <Okta>. Read the manager relationship, so a programme owner's line rolls
    up to whoever owns the budget above them.
    
    <Marketo>. Read spend and performance per campaign, so cost per outcome is
    derived rather than typed.
    
    <Google Sheets>. Take the plan in the shape it was built, a tab per
    programme and all, rather than asking anybody to retype it.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  48. Marketing

    content calendar with approvals

    One calendar covering every channel, with review routed by what the content contains rather than by who remembers to ask. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. One calendar, every channel
    
    In this Helix project, build me a content calendar with approvals.
    
    One record per item: title, type, channel, campaign, author, owner, target
    publish date, actual publish date, status, audience, primary message, url,
    and a link to the draft.
    
    Types to seed: blog post, email, social post, landing page, press release,
    customer story, product announcement, webinar, paid ad.
    
    Give me a calendar view filterable by channel, campaign, owner and status,
    and a list view for people who prefer one. One calendar covering every
    channel, with filters, rather than one per team. Separate calendars are
    how two campaigns land on the same day and how an email goes out before
    the page it links to.
    
    Add conflict detection: more than one item in the same channel on the same
    day, or two items aimed at the same audience in the same week. Warn, do
    not block.
    
    And a campaign view that groups every item in a campaign with its
    dependency order, so it is obvious when something is scheduled out of
    sequence.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Route review by what the content contains
    
    Now the rule that prevents the worst outcome.
    
    Put review rules in a config file. Each has a trigger and the reviewer role
    it requires. Seed it with: names a customer, makes a performance or
    comparison claim, mentions pricing, commits to future functionality, quotes
    a person, uses a partner or third-party brand, touches a regulated topic,
    targets a regulated market.
    
    The author answers a short checklist at submission and the app derives the
    required reviewers from the answers. Do not ask the author to pick
    reviewers. Relying on memory is exactly the failure this exists to
    prevent.
    
    Then add a safety net: scan the draft for signals that contradict the
    checklist, like a percentage, a superlative, a currency amount, or a
    customer name from a list I maintain. Flag any mismatch for the author to
    confirm before submitting.
    
    Show the author which reviewers their answers triggered and why. Route
    reviews in parallel where they are independent, in sequence where one
    depends on another.
    
    ## 3. Feedback that cannot quietly go unaddressed
    
    Reviewers see the draft, the checklist answers, why they were routed in, and
    what they are being asked to confirm. A legal reviewer looking at one claim
    should not have to read a whole blog post to find it.
    
    Give comments a type: required change, suggestion, or question. Each has a
    state of open or resolved and an owner. Approval is blocked while any
    required change is open. A suggestion never blocks.
    
    Then the rule that prevents a whole class of problem: bind approvals to a
    specific version. Editing a draft after approval invalidates the affected
    approvals and says which and why. It is unpopular for about a week and
    then nobody wants to go back.
    
    Add deputies per reviewer role with automatic reroute, and derive a due
    date on every review from the publish date minus a lead time I configure
    per content type. Give the author one view of everything outstanding and
    who holds it.
    
    ## 4. The published record, and how to need less review
    
    On publish, record the actual date, the final version, the live url, and the
    approvals in place at that moment. Keep that separately from the planned
    item, because plans and reality diverge and the record is what matters
    later.
    
    Make the archive searchable by claim type, customer named, and campaign.
    When a customer relationship changes or a claim is retired, "where have we
    said this" needs an answer in minutes.
    
    Report published against planned by month and channel, average time in
    review by reviewer role, and items published without a required approval,
    which should be zero. Plus the most frequently triggered review rules.
    
    Then use that last report to build a pre-approved claims library:
    statements already cleared, with expiry dates, that authors can use without
    triggering a review. Most review load is the same claims being cleared over
    and over, and this is where the time comes back.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Google Drive>. Read the draft to scan for claims, customer names and
    pricing, which is the safety net under the checklist.
    
    <Okta>. Resolve reviewer roles, so an approval carries a verified
    identity.
    
    <Contentful>. Read what actually published and when, and the live url for
    the record.
    
    <Slack>. Route reviews and chase them against the lead time for that
    content type.
    
    <Google Analytics>. Attach performance to each published item, so the
    archive is not just a record.
    
    <Notion>. Read drafts where writers actually work, rather than asking them
    to move.
    
    <Gmail>. Send the review request with the specific claim highlighted, not
    the whole post.
    
    <Snowflake>. Keep the published record queryable, so where-have-we-said-
    this is a query.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  49. Marketing

    event management tracker

    Run the logistics, capture leads with context, attribute pipeline honestly over a real window, and know before you book again. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Logistics that move when the date moves
    
    In this Helix project, build me an event management tracker.
    
    An event records: name, type (conference, our own event, webinar, dinner,
    roadshow), dates, location, the objective as a number, the audience, the
    owner, and the status.
    
    Then tasks, generated from templates by event type, with every due date
    expressed as an offset from the event date rather than a fixed date.
    Artwork due six weeks before, shipping cut-off three weeks before, badge
    list two weeks before, staffing confirmed one week before, follow-up
    within three days after.
    
    Event dates move, and when they do the whole plan should move with them
    rather than someone rebuilding a spreadsheet.
    
    Each task has an owning team and an owner, and anything past its due date
    escalates. The logistics risk in events is almost entirely missed
    deadlines, and the expensive ones are the ones with no second chance:
    artwork, shipping, and the badge list.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Count the whole cost
    
    Now costs, and be complete about it.
    
    Record sponsorship, stand build and design, shipping, travel,
    accommodation, food, giveaways, and any agency fees. Then record staff
    days: who attended, for how many days including travel, valued at a rate
    I set per role.
    
    Show the total, and show it split between cash spend and staff time. Most
    event post-mortems quote the sponsorship invoice, and the real cost is
    routinely twice that once four people have flown somewhere for three days.
    
    Compare committed against actual as the event approaches, and let me
    record a commitment when I sign rather than when I am invoiced, so the
    remaining budget is honest in the month it matters.
    
    And let me set the objective as a number before the event: pipeline,
    opportunities, meetings booked. Not "brand awareness". If the objective
    cannot be a number, the post-mortem cannot be a conclusion.
    
    ## 3. Capture the conversation, not the badge
    
    Build lead capture for use at the event, on a phone, in about twenty
    seconds.
    
    Name, company, role, and then the fields that matter: what they actually
    said, what they are trying to do, how warm it was on a simple scale, and
    what the next step should be. Let the person who spoke to them record who
    they were, because that is who should follow up.
    
    A badge scan with no context is a cold lead within a week, and everybody
    knows this and does it anyway because the alternative is typing on a
    stand. Make the alternative twenty seconds.
    
    Support offline entry that syncs later. Conference wifi is bad in a
    predictable way.
    
    Then follow-up: assign each lead an owner and a due date derived from the
    event, chase the ones not actioned, and report follow-up rate per person.
    Leads going cold in the week after an event is where most of the money
    actually goes.
    
    ## 4. Decide before, measure after
    
    Set the attribution window before the event runs, and record it on the event
    record. Ninety days, a hundred and eighty, whatever fits your cycle.
    Deciding the window afterwards is how every event turns out to have been a
    success.
    
    Then measure inside it: opportunities created from event leads,
    opportunities influenced where an attendee was already in an open deal,
    and pipeline value for each. Keep sourced and influenced separate rather
    than adding them together, because adding them is how a number becomes
    unbelievable.
    
    Derive cost per lead, cost per opportunity and cost per pipeline pound,
    using the full cost including staff time.
    
    Judge on cost per opportunity, and compare events only against other
    events. Comparing an event to paid search on cost per lead reliably
    produces the wrong decision, because they produce different kinds of
    pipeline that convert differently.
    
    Then a year-on-year view per recurring event, which is the report that
    actually decides whether to book again.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Push captured leads with their context, and read back the
    opportunities they became for attribution.
    
    <NetSuite>. Read committed and invoiced event costs, so the full cost is
    not a spreadsheet estimate.
    
    <Workday>. Read the role and cost rate of the staff you send, which is
    what a staff day cost is calculated from.
    
    <Slack>. Assign follow-up and chase it, because leads going cold in the
    first week is where the money goes.
    
    <Okta>. Verify whoever is on the stand before they can capture a lead,
    since this is personal data collected in a hurry on a shared device.
    
    <Marketo>. Push captured leads into nurture the same day, not the week
    after.
    
    <Brex>. Read the actual travel and stand spend rather than an estimate.
    
    <Google Sheets>. Import the badge scan export, which every event organiser
    hands you as a spreadsheet.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.
  50. Marketing

    lead routing app

    Route every lead to a named person in seconds, by rules you can read, with nothing ever landing in a pool nobody owns. Prompts to build it, and what it takes to run it.

    Read the guide

    ## 1. Rules a person can read
    
    In this Helix project, build me a lead routing app.
    
    A lead arrives with: name, email, company, job title, country, company
    size if we know it, the source, what they asked for, and any campaign or
    form reference.
    
    Enrich it where I can supply a source: match the email domain to an
    existing account or open opportunity first, because an inbound from a live
    deal should never be treated as a new lead.
    
    Then rules, as an ordered list I can read top to bottom. Each rule has
    conditions over the lead's attributes and a destination, and the first
    match wins. Show me the order and let me reorder it.
    
    Seed with the ones every company needs: named accounts go to their owner,
    existing customers go to their success manager, anything matching an open
    opportunity goes to that rep, then territory and segment rules, then
    product interest.
    
    Let me test a rule set against a batch of past leads and show me where
    each one would have gone before I turn anything on.
    
    I sign in through Helix, so do not build a login page. Read the signed-in
    user from the runtime. And do not put any key or connection string in the
    code: if this needs to reach another system, tell me and I will create the
    connection in my workspace.
    
    ## 2. Nothing lands unowned
    
    Now the part that prevents the expensive failure.
    
    Require a fallback destination: a named person who receives anything the
    rules did not anticipate. Not a pool, not a shared inbox, not a queue
    somebody checks on Mondays. Every routing system has cases its rules did
    not foresee, and the difference between a good one and a bad one is
    whether those reach a person.
    
    Then handle availability. Before assigning, check whether the destination
    is out of office, over a capacity limit I set, or has leave booked. If
    they are unavailable, route to their named deputy and record that this is
    what happened. A perfect rule that assigns a hot inbound to somebody on
    holiday is a lost lead with extra steps.
    
    Support round-robin inside a rule, but only inside one. Round-robin as the
    top-level strategy sends an enterprise inbound to whoever happens to be
    next, which is fair to the reps and expensive for the company.
    
    Alert on anything unassigned for more than a few minutes. That should
    never happen, and when it does it is the most urgent thing in the app.
    
    ## 3. Measure to first contact, not to assignment
    
    Track two clocks and keep them separate.
    
    Time from arrival to assignment, which should be seconds. And time from
    arrival to first contact, which is the one that correlates with
    conversion and the one almost nobody measures.
    
    A lead assigned in four seconds and contacted in two days was not routed
    well. It was assigned well, which is not the same thing.
    
    Show each rep their unactioned leads ordered by age, and escalate anything
    past a threshold I set to their manager. Then reassign, with the reason
    recorded, if it goes past a second threshold.
    
    Report median and worst-case time to first contact by rep, by source and
    by segment. Include an out-of-hours breakdown, because the weekend gap is
    usually where the worst numbers hide and an aggregate median conceals it
    completely.
    
    ## 4. Record why, because someone will ask
    
    Log every routing decision: the lead as it looked at that moment, which rule
    matched, which rules were evaluated and skipped, the destination, whether
    a fallback or deputy was used, and the timestamp.
    
    Routing disputes happen weekly. "Why did I not get that lead" is
    unanswerable without this, and answerable in ten seconds with it.
    
    Then report on the rules themselves. Which rules fire most, which have
    never fired at all, and how often the fallback is used. A fallback firing
    frequently is not a fallback doing its job, it is a rule set with a gap in
    it, and the leads it caught are the specification for the rule you are
    missing.
    
    And report leads by source against opportunities created, so the routing
    data doubles as a source quality report you did not have to build
    separately.
    
    ## 5. Connect it to real systems
    
    Now connect it to the systems we actually run, so it works on real data
    rather than the rows you seeded.
    
    Anything in angle brackets is a placeholder. Swap it for whatever we use
    instead, and have the app name the connection it wants rather than assume
    a vendor, so changing my mind later is a config change and not a rewrite.
    
    <Salesforce>. Match an inbound against existing accounts and open
    opportunities, then write the assignment.
    
    <Okta>. Read the current sales roster and its groups, so a rule never
    assigns to somebody who has left or is not on that team.
    
    <your website forms>. Take the inbound the moment it arrives, because time
    to first contact is the metric.
    
    <Slack>. Tell the rep they have a lead, and escalate anything unactioned
    to their manager.
    
    <Marketo>. Read form fills and enrichment before routing, so the rules
    have something to match on.
    
    <Outreach>. Put the lead into a sequence the moment it is assigned, which
    is what time to first contact measures.
    
    <Snowflake>. Read historical routing outcomes, so a rule set can be tested
    before it is switched on.
    
    Only write where I have said to write. Everything else is read only.
    
    Do not write a key, a token or a connection string anywhere in the code,
    and do not ask me to paste one. Tell me which connections you need and I
    will create each as an authentication in my Helix workspace. Reference
    them by alias.
    
    ## 6. Ship it
    
    Deploy my app.

Helix is the governed runtime for AI-built apps

Deploy what your teams build, put SSO in front of it, connect it with managed credentials, and give every app a named owner.