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.
Your private status link is on its way to your inbox.
50 apps
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
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.
## 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.
No apps match that. Try a shorter word, or clear the filter.
Deploy what your teams build, put SSO in front of it, connect it with managed credentials, and give every app a named owner.
Your private status link is on its way to your inbox.