question.servicesTalk to us

question.services · the services arm of the question.* family · Powered by question.technology

The part a person does, described as work a person does.

The question.* family is one response engine with several front doors. This is the arm where a person does the work — and where every task is described by the mechanism that performs it, not by an outcome that implies a console.

There is no services marketplace, no bookable calendar, no scoping wizard and no client portal. Every engagement starts as an email a person reads, and every task below names the mechanism that performs it. Money is off here. Nothing here is AI.

A person, not a portalevery engagement starts as an email somebody on the team reads
No identity columna response row has no name, email, network address, account or session field
Forced row securitythe response tables run row-level security enabled and forced, per-owner
Three answer shapesopen text, a 1-to-5 scale, and single choice, enforced by the database

One engine, several front doors, and one arm made of people

The question.* family is one shared response engine with front doors aimed at different readers, all built by one team, on one security model, one support operation, and one platform.

question.technology is the engine: the shared question-authoring and response-collection surface the whole family runs on.

question.software is the classroom front door: where a teacher writes questions, runs them with a class, and reviews the responses.

question.management is the district-operations facet: what the organization-scoped model guarantees across more than one building, and what still takes a request.

question.company is the venture behind the family: who builds it, how it operates, and its honest stage.

question.services — this page — is the arm that fulfils the requests the other pages point at. When question.management says “that is a request to us,” this is the page describing what happens after you send it.

Powered by question.technology. You pay for the platform and the work, not repeatedly for the same engine wearing different brands.

What we do

Six things a person on this team does for you

A services page is the easiest place in the world to describe hand-work in the grammar of a shipped feature. “Roster provisioning is supported” is true about the outcome and false about the mechanism, and the difference matters to anyone planning a term around it. So each card below names the mechanism — who performs it, by what means — alongside the outcome, and cites the constraint in the real database the work rides on.

We write the question set with you

Done by a person, on request

Most of the value in asking a school community anything is in the wording. We sit with the people who will read the results, work out what decision the answers are supposed to inform, and write the set against the three answer shapes the database actually admits: open text, a 1-to-5 scale, and single choice. A question that cannot be stored as one of those three is rewritten before it is published, not after the responses are in.

How it is actually performed: A person on our team drafts it, you edit it, we publish it into your organization. There is no question-writing wizard and no template gallery.

Evidenceck_qt_question_type CHECK (type IN ('text','scale','choice')); ck_qt_question_choice_has_options; SCALE_RANGE = {min:1,max:5} in packages/shared/src/question-technology-bank.ts.

We stand up your organization

Done by a person, on request

Your school or district exists on the engine as one organization row, and every question set and every stored response carries that organization's id. Setting that up is not a signup form you fill in: we create the organization, attach it to the right billing and support arrangement, and tell you the identifiers you will see in an export.

How it is actually performed: A person creates the organization row and tells you its identifier. There is no self-serve organization creation screen.

Evidenceqt_submission.owner_org_id NOT NULL with a foreign key to partner_org(id) ON DELETE RESTRICT -- an organization row cannot be deleted out from under its responses.

We provision the staff accounts

Done by a person, on request

The people who will build and run question sets need accounts with staff capability inside your organization. We create them on request, one at a time, from a list you send us. This is genuinely manual work and we would rather describe it as manual work than call it onboarding automation.

How it is actually performed: A person provisions each staff account by hand. There is no shipped single-sign-on or roster-sync connector, so nothing imports your staff list on its own.

EvidenceThe magic-link exchange path (apps/api/src/routes/auth.ts, POST /auth/magic-link/verify) creates no account at all -- it looks the address up and refuses it 404 no_account when nothing is on file. Of the two magic-link routes, only verify-token provisions, and only when the address is already on file as a student contact in the link's school; it then grants role 'parent' (or 'alumni' for an alumni link) scoped to that one school. Federated sign-in provisions too -- SSO, SAML and an LTI launch each land a least-privileged 'student' account with no school scope at all. What none of those paths grants is staff, admin, billing or roster capability over an organization that already exists. Staff capability is set by us.

We migrate the survey you already run

Done by a person, on request

Most schools that come to us already ask their community something once a year, usually in a spreadsheet or a form built by whoever had time. We take that instrument and rewrite it into published question sets, keeping the questions whose wording still works and flagging the ones that cannot be stored honestly in three answer shapes.

How it is actually performed: A person reads your existing instrument and rewrites it. There is no importer, and no file you upload is parsed by software on our side.

Evidenceqt_question_set.status CHECK (status IN ('draft','published','archived')) -- a migrated set moves through those three states, and nothing else.

We address the set to the audiences you care about

Done by a person, on request

A question set can be pointed at the specific groups you want to hear from. The engine carries a fixed list of twelve declared audiences, and a respondent self-declares which of them apply to them. Choosing which audiences a set is for, and what to do when one of them is a group of six people, is part of the engagement rather than a setting you toggle alone.

How it is actually performed: A person helps you choose the audiences and warns you where a small group would be legible in the results. The declared audience is a claim about a role, never a verified identity.

EvidenceQUESTION_REALMS enumerates twelve: parent, teacher, adviser, administrator, superintendent, studio, rep, department-chair, it-director, booster-pta, board-member, district-admin (packages/shared/src/question-technology-bank.ts).

We run the export and the deletion

Done by a person, on request

When you want everything your organization holds, or want it gone, that is a request to a person, and a person does it. We would rather tell you a human runs it than put a button on a page that does not have one behind it.

How it is actually performed: A person on the team runs the export or the deletion against your organization and confirms it back to you in writing. There is no self-serve export button and no self-serve deletion button.

Evidenceqt_submission and its sibling tables carry ROW LEVEL SECURITY ENABLEd and FORCEd, under the per-owner policy qt_submission_owner_iso (migration 1140_qt_owner_anchor_rls), whose first arm is is_system() -- so an export or deletion run by our own tooling runs under the system scope, and any other caller is confined to the owner it resolves to.

If what you need is not on this list, say so in an email. The honest answer is sometimes that we would have to build it, and that answer is worth more to you than a sixth card invented to look complete.

Provable now

What is running underneath every engagement

Hiring people to work inside your data is a bigger ask than buying software, so the guarantees underneath the work should be checkable rather than promised. Everything in this section is a property of the response engine running today, read off the real migration and the shared library, and each card names where it is enforced so you can check it instead of trusting us.

A response row has no identity column

Enforced by the database today

Whatever we do for you by hand, the row a response is written to has four columns and none of them names a person. There is nothing for a later mistake, an over-eager export, or a well-meaning service engagement to accidentally fill in, because the column does not exist.

Evidenceqt_submission columns = id, owner_org_id, submitted_at, moderation_state; the applied table's column set is asserted against information_schema by packages/db/src/migration-1103-zero-pii.test.ts.

The organization is set by the server, not by the caller

Enforced by the database today

The organization a response belongs to is inherited server-side from the question or set that was resolved. It is never read from the payload of the person answering. That is what keeps an unauthenticated answer path from becoming a way to write into somebody else's organization.

EvidenceThe migration states owner_org_id is INHERITED server-side from the resolved question/set and NEVER read from the anonymous caller's payload -- a caller-supplied owner on an unauthenticated route would be a cross-owner write primitive.

The stored time is coarsened to the hour, in the database

Enforced by the database today

A stored response keeps only the hour it arrived. The default coarsens it and a database check makes precision impossible to store, so a route that tried to write a precise moment is rejected rather than quietly recorded. No service engagement can opt out of that.

Evidenceck_qt_submission_submitted_at_hour_coarse CHECK (submitted_at = date_trunc('hour', submitted_at)); DEFAULT date_trunc('hour', now()).

A flagged response is labelled, not deleted

Enforced by the database today

Moderation runs before a response is stored, and the verdict is one of two values on the row itself. A response the moderator flags is kept and marked, so what happened to it is visible in an export rather than silently missing from one.

Evidenceck_qt_submission_moderation_state CHECK (moderation_state IN ('accepted','flagged')).

Row-level security is forced, not merely enabled

Enforced by the database today

The response tables carry row-level security both enabled and forced, under a per-owner policy. Forced matters: it means the table owner does not get a quiet exemption from its own policy, which is exactly the exemption a services engagement running under an elevated account would otherwise inherit.

EvidenceALTER TABLE qt_submission ENABLE ROW LEVEL SECURITY; ALTER TABLE qt_submission FORCE ROW LEVEL SECURITY; POLICY qt_submission_owner_iso USING (is_system() OR owner_org_id = current_studio_id() OR owner_school_id = ANY(current_school_ids())) -- migration 1140_qt_owner_anchor_rls, which DROPped the earlier qt_submission_system_only policy this line used to name.

None of these are settings an engagement can turn off. They are constraints on the tables themselves, which is the point: a person working in a hurry cannot widen them by accident.

Radically legible about our stage

What we are, and what we are not

Here is the ledger, out loud. The left column is what a services page usually implies without saying. The right column is the honest version here.

The left column is what a services page usually implies. The right column is the honest version here, stated so an absence never reads as an accident.
What a services page usually impliesThe honest version here
A services catalogue with a bookable calendar and a scoping wizardThere is no catalogue, no calendar and no wizard. Every engagement on this page starts as an email that a person on the team reads and answers.
A published day rate, a retainer tier, or a package priceThere is no rate on this page and no checkout on it. Money is off here. What an engagement costs is a direct conversation, because there is no self-serve services tier to charge against.
A client portal where you watch your engagement progressThere is no client portal. You hear from a person by email, and the artifacts of an engagement are the question sets in your own organization.
Roster provisioning described as an integrationThere is no shipped single-sign-on or roster-sync connector. When this page says we provision staff accounts it means a person creates them by hand from a list you send us.
A team page with headcount, bios and years of combined experienceThere is no headcount figure and no combined-experience number on this page, because inventing one is exactly the kind of thing this page exists to avoid. This is a founder-led venture and you will be talking to the people who build the product.
Case studies with named districts and percentage improvementsThere is no logo wall, no named client and no percentage on this page. We have not published a case study we could stand behind at this stage, so we publish none.
A guarantee of turnaround timeThere is no turnaround figure here, because we have not measured one to a standard worth publishing. What we will do is tell you a real date when we scope your engagement, and tell you if it moves.

Naming the gaps is how the provable parts above stay believable. Anyone reading this page knows exactly what they are buying and exactly what still requires an email.

How an engagement runs

Six steps, and none of them is a console

This is the real order of events, written so you can plan a timeline against reality rather than against an assumed portal. Where a step is slow because a person is doing it by hand, the step says so.

Step 1

You email us and describe the decision

Not the survey — the decision the survey is meant to inform. The most useful first message says who you need to hear from, what you will do differently depending on the answer, and when you need it.

Step 2

We scope it back to you in writing

You get a written scope naming what we will do, what you will do, and what we are not doing. If part of what you asked for does not exist in the product, that sentence is in the scope rather than discovered later.

Step 3

We stand up your organization and your staff accounts

A person creates the organization row and provisions each staff account by hand from the list you send. Nothing imports your staff list on its own, and we will tell you how long the list takes rather than implying it is instant.

Step 4

We draft the question set and you edit it

We write the first draft against the three answer shapes the database admits, you mark it up, and we publish the edited version into your organization. The draft-to-published move is a real state change on the set, not a metaphor.

Step 5

It runs, and moderation runs before anything is stored

Responses arrive into your organization with the hour they arrived and a moderation verdict. A flagged response is kept and marked so you can see it, rather than disappearing from your results without explanation.

Step 6

We read the results with you, and hand you the export

A person walks the results with you and runs the export. If you would rather never speak to us again after that, the export is yours and the question sets stay in your organization.

Steps three and four are the ones that take real calendar time, because a person is typing. We would rather you plan around that than be surprised by it in week two.

Which reader are you?

A services page is read by a principal, a district administrator, a technology director, a business officer, a parent and a reporter, and they do not want the same thing from it. Here is where each should start.

Who you are, where to start on this page, and why.
You areStart withBecause
A principal who needs one honest answer from a communityWhat we do, then How an engagement runsSee which parts are a person's work and roughly what order they happen in before you commit a term to it.
A district administrator comparing this to hiring a consultantWhat a services page usually impliesThe ledger is the fastest way to see exactly which conveniences we do not have, before you ask us for them.
A technology director checking where the data landsWhat is running underneathEvery guarantee names the constraint that enforces it, so you can check the claim rather than trust it.
A business or procurement officerMoney, said plainly, then ContactThere is no rate card here on purpose; the money section says why, and what a real conversation covers.
A parent or guardian who was asked to answer somethingTrust and dataSee exactly what a stored response does and does not contain, in the columns that exist.
A reporter or analyst checking a claimWhat this page does not claimEvery absence on this page is written down; if you find one that is not, tell us and we will write it down.

Trust & data

What it means to let people work inside your data

This is the question a services arm has to answer that a software page does not: what happens when a human being on our side is doing work inside your organization. Rather than an absolute promise, here is the same scoped custody register the rest of the family states, applied to the case where a person is at the keyboard.

A services engagement does not widen what a response row holds

Hiring us to run a question set does not add a name, an email address, an IP address, a device fingerprint or a session to a response row. Those columns do not exist on the table, so there is nothing for an engagement to switch on.

Evidenceqt_submission holds exactly four columns -- id, owner_org_id, submitted_at, moderation_state -- migration 1103_question_technology. That column set is asserted against the REAL applied table through information_schema by packages/db/src/migration-1103-zero-pii.test.ts, so adding an identity column turns that test RED rather than passing review.

Your organization is a wall, and the wall is forced

Every question set and response carries your organization's id, and the tables run row-level security both enabled and forced, under a per-owner policy. Forced means the table owner gets no quiet exemption from the policy.

EvidenceENABLE plus FORCE ROW LEVEL SECURITY on all eight qt_ tables, migration 1103_question_technology and re-asserted in migration 1140_qt_owner_anchor_rls, which replaced the eight earlier system-only policies with per-owner ones: qt_submission_owner_iso USING (is_system() OR owner_org_id = current_studio_id() OR owner_school_id = ANY(current_school_ids())).

A minor’s record is consent-gated

A minor's name, face and record are consent-gated and not publicly browsable, and consent can be withdrawn. That is the standing rule across the estate and a services engagement does not create an exception to it.

Evidencestudent_consent, unique on (student_id, purpose), with state defaulting to pending -- pending is NOT granted, so the gate fails closed. Withdrawal is a recorded event rather than an erasure: student_consent_ledger, migration 0547_consent_immutable_ledger, carries ck_student_consent_ledger_event_kind CHECK (event_kind IN ('grant','withdraw')), a SHA-256 prev_hash / entry_hash chain, an application grant of SELECT and INSERT only, and the BEFORE UPDATE OR DELETE trigger trg_student_consent_ledger_append_only, which raises.

No certification claim

FERPA does not certify products, so we claim no certification and make no blanket compliance claim. The product is designed to support a school's obligations, and its data practices are documented for review.

EvidenceThis row asserts a refusal rather than a capability, so its artifact is the guard that keeps the refusal true: question-services.test.ts denies the certification-claim string class over this rendered body, keyed on FERPA and on COPPA, and the surrounding bans each carry a positive control and a negative-universality arm.

What if you want everything back, or want it gone? Both exist today by direct request: a person on the team runs the export or the deletion for your organization and confirms it back to you in writing. Neither is a button on this page, because there is no button behind it.

This describes the intended data model and how an engagement works inside it; it does not promise certified compliance, zero logging, or automatic deletion, and it claims no FERPA or COPPA certification.

Money, said plainly

Money is off on this page

There is no rate on this page and no checkout on it. Nothing here takes a payment, captures a card, or converts anyone to a paid plan. Because there is no self-serve services tier, what an engagement costs is a direct conversation rather than a table.

You might reasonably read that as a way to avoid naming a number. The honest reason is narrower: self-serve services billing has not been built, so a published rate would be a number this page has no mechanism to charge against, and we would rather write that sentence than publish the number.

When a scope goes to you it names what the work is, what it costs, and what is out of scope, in writing, before anyone starts. That is the document with the number in it, and it is a document a person wrote.

FAQ

Questions people actually ask before hiring us

What exactly am I buying here?

People-hours around a response engine that already runs: writing the question set, standing up your organization, provisioning staff accounts by hand, migrating an instrument you already use, and running the export. Each of those names the mechanism that performs it on this page, so you can tell hand-work from software.

Can I book an engagement from this page?

No. There is no calendar, no booking form and no scoping wizard here. You email the address on this page and a person reads it and answers you.

Is signing up self-serve?

Careful answer, because both sloppy versions of it are false. Verifying a magic link creates no account — that route looks your address up and refuses it when there is nothing on file. One sibling route does provision, and only on evidence your school staged itself: the address must already be on file as a student contact in the link’s school. It then lands a guardian-level 'parent' account (or 'alumni' for an alumni link) scoped to that one school, which grants no staff, admin, billing or roster capability. What no public route does is hand anyone STAFF access to an organization’s question sets. That is provisioned by a person on our team, one account at a time.

Do you connect to our single sign-on or our student information system?

There is no shipped connector for either. We provision staff accounts by hand from a list you send us. If your school needs a real integration, say so and it would be built as one rather than implied here before it exists.

What does an engagement cost?

There is no rate on this page and no checkout anywhere on it. Money is off here. Cost is a direct conversation, because there is no self-serve services tier to charge against, and we would rather say that than publish a number this page has no way to take payment on.

Do you use AI to write the questions or read the answers?

No. Nothing here is AI. No model writes a question, scores a response, summarises a result, or grades a student. The drafting on this page is a person writing sentences.

Who can see the responses while you are working inside our organization?

Responses live behind your organization’s id, on tables with row-level security enabled and forced under a per-owner policy whose first arm is the system scope our own tooling uses. A response row holds no name, email address, network address or session, so there is no identity in it for anyone to see.

What if a group we ask is very small?

Then a result about that group can be legible even without a name attached, and we will say so during scoping. A respondent declares which audiences apply to them from a fixed list of twelve; a rare combination of those declarations is itself distinguishing, and that is a design consideration we raise rather than a problem we pretend a column solves.

How is question.services different from question.management?

question.management is the district-operations facet: what the org-scoped data model guarantees a district and what a district still has to ask for. question.services is the arm that DOES the asking-for: the actual people-hours, described by the mechanism that performs them.

Can we get our data out, or deleted?

Both, by asking a person. There is no self-serve export button and no self-serve deletion button, and we would rather describe the request than put a control on a page that has nothing behind it. An organization row cannot be removed out from under its responses by accident: the foreign key restricts it.

Can I check the claims on this page?

The evidence lines name real table constraints, real policies and real exported symbols, so those claims can be checked rather than believed. Any other claim on this page can be raised with us directly and we will either show you where it is enforced or take it down.

Contact

Talk to the people who would do the work

Whether you are a principal with one question to ask a community, a district administrator weighing this against a consultant, or a reporter checking a claim on this page, the door is the same one, and a person reads it.

Email [email protected]. There is no form on this page, no card asked for, and no student data requested — please do not send any.

The most useful first message describes the decision the answers are supposed to inform, who you need to hear from, and when. That is enough for us to tell you whether this is work worth paying for or something you can do without us.

Powered by question.technology · a Stanley Studios venture · money is off · nothing here is AI.

What this page does not claim

The response engine this arm works on runs in production today, every response is scoped to one organization, and the tables carry row-level security enabled and forced. That is the strongest true thing here.

There is no services marketplace, no bookable calendar, no scoping wizard, no client portal, no shipped single-sign-on or roster-sync connector, no self-serve export button and no self-serve deletion button. Every one of those is a person and an email.

There is no client logo wall, no named case study, no engagement count, no headcount figure and no turnaround guarantee, because none exist worth publishing and none may be invented to fill the space.

One claim is deliberately narrow, because the broader versions are all false: verifying a magic link creates no account, and of the two magic-link routes, only verify-token provisions — it needs evidence your school staged itself, the address must already be on file as a student contact in that school, and the new guardian or alumni account is then scoped to that single school. Federated sign-in provisions as well: an SSO, SAML or LTI launch lands a least-privileged account with no school scope at all. What none of those grants is staff, admin, billing or roster capability over an organization that already exists — creating an account is ordinary, and capability is the thing withheld. Staff access to an organization’s question sets is provisioned by a person.

Money is off: no rate and no checkout. Nothing here is AI. A minor’s record is consent-gated and not publicly browsable, and we claim no FERPA or COPPA certification.