← All privacy impact assessments

PIA: Targeted notices — task notices and event detail confirmations

Approved by the founder, 26 October 2026. §12, "Creator notices and prompts", and the rows marked "Creator notices" in §§2, 3.2, 6 and 9. Tasks Option B adds "Can't do this": a member who can't do a task gives it back, asks someone else, or says it doesn't need doing, and only the task's creator is told, once, quietly, in the Tasks tab's notice strip — no push and no chat post. The creator may also be asked, on their own phone, about a task nobody has taken for three days or one more than fourteen days overdue. Nothing is reassigned or closed by itself, nothing counts per person, and child accounts get no timed prompts. It collects one optional short note and who skipped a task.

Planned, 10 October 2026: three notifications nobody asked for. The app is being changed so that it may interrupt a member to tell them a person did something that concerns them — somebody else gave them a task, a person joined one of their groups, or their request to join or connect was approved. Until now the app only notified a member about something they had asked for themselves, or because another member chose to send them a notice. None of it is built. It collects nothing new: each notification is set off by a fact the app already holds — an assignment, a membership, an approved request — and no AI model is asked whether to send one.

The task one is a change of trigger, not of transport. Telling the people a task was assigned to already works exactly as this document describes — one notice per task, one row per recipient, the group's name and the one approved generic line on the lock screen, identifiers only, nothing that carries the task's title. What changes is who decides: today the member creating the task ticks a box (off unless they tick it); from this change, assigning a task to somebody is itself enough. A task created by the member's own assistant, and a task that already needs their approval and already notifies them, are both excluded.

What bounds it. Every such notification names a group and a person and nothing else, and in a Phones-only group it names nobody. A member gets at most three notifications a day that they did not ask for, counting these, the first-week suggestions and the existing daily catch-up together; notifications about the same thing within ten minutes are combined into one; and reminders a member set, or a daily brief they chose, do not count towards it. Each kind has its own switch, and the switch can be found again. Child accounts, the shared display's account and profiles are excluded and keep the old rule — nothing interrupts them unless somebody asked for it.

The new risk, stated plainly. Today a member can only be interrupted about a task if the person creating it chose to interrupt them; afterwards, being given a task is enough. That is a real loss of quiet, and it is the trade this change makes deliberately: a member who joined and typed a list of jobs into the app heard nothing from it again. The protections offered against it are the three-a-day limit, the ten-minute combining, the per-kind switch, and the rule that the notification still never carries what the task says. What is not offered, and is accepted as residual: a member cannot stop another member assigning them a task, and cannot see who chose to notify them, because nothing records that choice any more.

Status: Draft, written before the code, and since revised as one half was built. Two features share one audience design and are assessed together: telling chosen members about a new task, and asking chosen members to confirm an event's details.

Build status, 18 September 2026: the event detail confirmation half and its reusable recipient-only delivery primitive are built. The database enforces one response per chosen recipient and current event version: the first confirm or owner-private "not now" wins, an identical repeat is a no-op, a conflicting repeat and a stale version are refused atomically, and different recipients answer independently. The shared chat card is one-per-request but is marked so the ordinary whole-group message trigger sends no push. The dedicated push carries only the request/group identifiers, the group name and the fixed generic lock-screen line; the event title, question and recipient list are never copied into it. Delivery is claimed on a stable request/recipient/device identity and uses the existing push-delivery receipt ledger. Save, request, card and delivery report structured outcomes, and a retry repeats only unfinished work.

Both halves are now built (task notices added later on 18 September 2026). A task notice has its own three tables — the notice, its recipients, and each recipient's own seen row — with the database enforcing that a recipient is an active member of the task's group, that there is one notice per task and one row per recipient, that a recipient's seen state is readable by that recipient alone, and that every row cascades from the task, the group and the member. Delivery rides the same identifier-only transport: one claim per notice, recipient, device and the moment that recipient was named, so a re-send that adds somebody else never pages the people already told, and a retry never pages a device twice. The sender is told that the notice was recorded and whether the notification went — never who has seen it. A child account may be named (§7), and because a child's account has no assistant surface, their notices appear as a strip on their own task list instead. The words a recipient reads are composed on their device from the task and the roster; no model is involved. Written: 18 September 2026 · Last revised: 26 October 2026 (§12: creator notices and prompts, Tasks Option B PR2, approved by the founder) · 21 October 2026 (§11: muting one group's notifications, built) · 10 October 2026 (the amendment at the top: three planned notifications nobody asked for, and the limit on them) · 18 September 2026 (task notices built) Nothing here is legal advice. Children's Code citations are to the exposure draft; section numbers may move on registration (due 10 December 2026).


1. Purpose and scope

Today, when a member creates a task or wants an event's details checked, the app offers two blunt instruments: assign the task and hope the person notices, or announce it to the whole group's chat. This design adds a third, narrower one — calling a specific member's attention to a specific record, without interrupting everybody else:

The principle the whole design hangs on: targeting routes attention; it never creates a private channel. Choosing recipients decides whose attention surfaces raise a card and whose phone is interrupted. It does not hide the underlying task, event, request or question from the rest of the group, and the app says so wherever recipients are chosen.

In scope: the recipient model (who can be named, what a recipient row holds, who can read it), the notice and confirmation records, delivery and push behaviour, and what each party is ever shown about the others. Out of scope, covered elsewhere: the forwarded-email cards that will reuse this audience model (assessed in the group inbox assessment — which also records the one exception this design does not otherwise have: since 22 September 2026, a group's owner or admin reads and resolves an INBOX_PROPOSAL card whatever its audience, from the Mail Sifter item screen rather than the Assistant tab, so a card nobody named opens is not stranded until the 30-day sweep — a database read/update rule scoped to that one card TYPE, and no other targeted-notice surface gains an equivalent); invitations that cross a group boundary (assessed in the cross-group events assessment — nothing in this design crosses one); and task reminders a member schedules for themselves, which already ship. Those reminders are promises a member made to themselves, which is the first of the four reasons the app may interrupt anybody at all (the rule, and the three others added on 10 October 2026, are in the amendment at the top of this document).

2. Data involved

Kind Whose Children's? Sensitive? Free text?
A notice record: sender, the task or event it points at, the chosen recipients, when it was sent the sender's act, about a record the group already holds possibly — a recipient or a task's subject can be a child no new content — it carries identifiers; the words shown are composed on the reading device from rows the reader can already see no
A per-recipient seen state the recipient's own possibly no no
A detail-confirmation request: the event, which details are being checked (a closed list), the version being checked, and an optional short typed question the requester's possibly — the event can be about a child possibly — the question is typed by a person yes — the question, capped short
A confirmation: who confirmed, when, and which version of the event they were looking at the confirmer's possibly no no
A dismissal: that one chosen recipient set aside that version of the request, and when the recipient's own, readable only by them possibly no no
Creator notices (§12): that a member gave a task back or thinks it doesn't need doing — who, which task, who is told (the creator; an owner once the creator has left), when, and an optional note the member's own act, about a task the group already holds possibly — a member or the task's subject can be a child possibly — the note is typed by a person yes — the note, capped at 200 characters by the column
Creator notices (§12): an open "ask someone else": who asked whom to take which task, when, and an optional note the asker's possibly possibly yes — the note, capped the same way
Creator notices (§12): that a task was skipped — when, and by whom (two columns on the task) the creator's act (an admin's once the creator has left) possibly no no
Creator notices (§12): a member set aside a notice, an ask or one of the two prompts — which, and when the member's own, readable only by them possibly no no

Not collected, deliberately, and each absence is load-bearing:

3. Flows and locations

Data Device Supabase (Sydney, ap-southeast-2) Model provider
Notice and confirmation records, recipient rows, seen state written and read by members' devices stored as plain structured state, unsealed, the same as every other shared action card — see §3.1 never — no step of either feature involves a model
The typed confirmation question typed on the requester's device stored in plain text on the group-readable request row — §3.1 says why, and what bounds it never
The push notification shown on the recipient's lock screen dispatched through the existing push pipeline, with its delivery ledger never

3.1 Encryption tier, and what a Device-only group gets

The typed confirmation question is the only content in this feature, and it is stored in plain text in our database. It is a small structured field on a shared card, which is the same posture every other shared action card's payload already has — the app's end-to-end sealing covers large content a member authored (photographs, chat messages, an event's notes and place) under keys that exist only on devices, and deliberately does not cover the structured state our server has to be able to act on. Saying this plainly matters more than the choice itself: an operator holding our database can read a confirmation question, and no copy anywhere may imply otherwise.

Three consequences the build must honour:

3.2 Retention and deletion

Notices and confirmations are derived attention state about a record, not records in their own right, and the design's rule is that they never outlive the thing they point at:

4. Legal basis and consents

No new consent purpose is created and none is needed. Sending a notice is the sender's own deliberate act about a record the group already shares — the same basis as assigning the task in the first place — and nothing new is collected.

Nor is any new destination introduced, which is the accurate form of the claim. One path leaves the country, and it is the existing push path disclosed in §3: the device address, the group's name and the short lock-screen line, through the platform push services every notification this app already sends passes through. Beyond that payload, no household row or content is processed outside our Sydney database, and no model is called at any point. This feature adds another kind of push to that path; it does not add a recipient of anybody's data who was not already receiving pushes for this app.

Delivery respects each recipient's existing notification settings; a recipient who has turned notifications off still gets the in-app card and no push. The consent ledger is not touched: there is no switch here, because there is no new destination or kind of processing to consent to — the overseas push path is the one the app's existing notification disclosure already covers, and nothing in this feature widens what travels on it.

5. Risks and mitigations

Risk Who is harmed Mitigation Structural or conventional? Residual
The sender is shown which recipients have seen a notice — which is a read receipt, a feature this app removed for every member because showing anybody how others engaged with their material is what would change the app's legal position under the under-16 rules every member, and the app's own standing Seen state is readable by its own recipient alone, under a row policy that names them; no query the app ships returns another member's seen state; the standing source scan that keeps feedback features out of the chat and photo surfaces is extended over these new surfaces Structural for the read policy; the scan is test-pinned Acting on a notice reveals engagement inherently — a task completed is visible as a completed task. Accepted: that is the record, not a meter on the person
Dispatch status drifts into engagement status — "Sent ✓✓" becomes "Seen" one well-meant edit at a time recipients The design allows the sender exactly two statements, both about our own delivery machinery: the notice was recorded, and the push could or could not be dispatched (with Retry). Copy is pinned by test to say nothing about the person Conventional — copy, test-pinned A sender can still ask the recipient in person, which is the correct channel
A notice becomes a nag machine — repeated sends to the same person about the same record a member, often the least powerful one in the group Event confirmation has one request and one shared card per event; delivery has one stable claim per request, recipient and device. Retrying cannot stack a card or page the same device again. F17 still owes its own one-task/recipient uniqueness before it can reuse the transport Structural for the built event uniqueness and delivery key; the task half remains gated A member can still edit and deliberately re-ask about a genuinely new event version. Accepted — the current request is visible to the group
The same recipient confirms and dismisses concurrently, or a stale device answers after the event changed the recipient and the group's records One RPC locks the request/recipient pair and checks that both the request and response name the event's exact current version. The first response wins; the same repeat is a no-op; an opposite response or stale version is refused. Different recipients remain independent Structural — transaction lock, exact-version checks and recipient FK —
A confirmation is read as covering the current event after the event has changed whoever turns up at the old time A new stale confirmation cannot be written: the RPC refuses it. An already-recorded confirmation can become historical after a later edit, and every rendering beside the newer version says it covered the older one Structural for the write refusal and stored version; conventional for the sentence being rendered A member who reads only the tick and not the sentence can still be misled. Accepted, with the display rule test-pinned
Declining to confirm deletes the event or reads as declining to attend — the card-conflation failure this app has had before, where declining a dinner invitation deleted the dinner the whole group Confirmation cards get their own card identity that shares no resolution path with event proposals, invitations, or task approvals; declining removes the request from the decliner's attention and nothing else Structural — a distinct card kind, pinned the same way the existing prefixes are —
The short question becomes a private message lane inside a group whose conversations are deliberately all group-visible members not in the exchange, and children especially The question lives on the request record, which every active member of the group can read — recipients are who gets interrupted, not who gets to see. The recipient rows that are member-scoped carry no text at all Structural — there is no free-text column on any recipient-scoped row A determined pair can still exchange words by editing questions at each other. Accepted: the exchange is group-readable the whole time, which is what removes the incentive
The typed question holds something sensitive and sits in our database in plain text, unlike the group's photographs, chat and event notes whoever the question is about — often a child, since events about children are what get checked It is short by a constraint on the column itself, group-readable by design (so it is written knowing the household will read it), and never in a log; §3.1 states the posture rather than implying the sealing that covers other content covers this Structural for the cap (a database constraint, not a composer's limit) and for there being no recipient-scoped text column; the plaintext posture is stated, not mitigated Accepted, and it is the sharpest edge in this design. A member can type something regrettable into a field an operator could read. Sealing it would mean our server could not act on the card, and a private lane is the thing §5 refuses above
A notice outlives the task it points at, or survives a member's erasure as a name in a row a departed member, whose erasure would be incomplete Every row cascades from its parent record, group and member; the sender's name is resolved from the roster at render rather than stored as text (§3.2) Structural for the cascades; conventional for the render-time name resolution —
A departed member is named as a recipient, or departs while named the sender, whose ask silently reaches nobody Recipients are checked against active membership when the notice is written; a recipient who later leaves loses access with their membership, and the sender's next visit shows the request unanswered rather than pretending it is pending with someone Structural for the membership check; conventional for the honest display —
The shared chat card triggers the ordinary whole-group push, or a retry pages recipients twice every group member, especially the least powerful recipient Event-confirmation messages carry a request marker that makes notify_group_message return before dispatch. The dedicated transport atomically derives only active recipients from the exact current request version and claims a unique request/version/recipient/device ledger row before sending; same-version retries claim only rows explicitly recorded retryable and there is no whole-group fallback Structural — marker constraint, trigger arm, current-version and active-member batch claim, recipient/token validation and full unique delivery key A process death after the provider accepted a request but before a ticket was recorded is ambiguous; the row is marked unknown and is not automatically resent
A sealed or Device-only title is copied into a chat row, push payload or delivery log the household, especially a child named by the event The card link and push data carry identifiers only. The targeted dispatcher never queries the event title or question, and the delivery ledger stores operational identifiers/outcomes only. One generic lock-screen line is used for every privacy level Structural for the identifier-only card marker/ledger shape; source- and payload-tested for the dispatcher The group name still appears on the lock screen, accepted in §8

6. Structural versus conventional

Structural and built for event confirmation — the database enforces these; the client is not the boundary:

Structural and built for task notices — the same posture, with the differences named:

Creator notices (§12) — structural; the database enforces these:

Conventional and built for task notices: the sentence a recipient reads ("Sarah added a task for you", or "Sam sent you a task" when the sender is not its creator) is composed on the device and attributed to the member who named that recipient; the sender's status line names only the notice and the notification; the source scan that keeps feedback features out of the app covers the new module, slice and both screens.

Conventional — held by copy, tests and review:

7. Best interests of the child

A child who is a member can be a recipient — children hold tasks, attend events, and are exactly who "the bins are yours tonight" is often for. The design's obligations to them:

No model is involved anywhere in this feature, so nothing about a child travels to one.

8. Residual risk we accept

9. Review trigger

Both features are built and this document now describes them. It is re-read if any change proposes:

10. Checklist against exposure draft s 38(2)

s 38(2) Requires Answered in
(a) nature, scope, context, flow and purposes of handling children's personal information §§1–3
(b) why the collection is strictly necessary §2 — the records are identifiers over rows the group already holds; the one typed field is the question the feature exists to ask
(c) lawful and fair collection §4
(d) consistency with the best interests of the child §7
(e) how we comply with the Code and the Act §4 and §6
(f) risk of harm to children §5, §7

s 38(3): this assessment preceded the build and was revised against the event implementation; it still precedes and gates F17. s 39: listed on the published register.

11. Muting one group's notifications

Built, 21 October 2026. A member can mute one group's notifications on their own account for 8 hours, for a week, or until they turn it back on. They do it from the group's own screen, just below its children, and they see and undo every mute under You → Notifications → Muted groups. Muting and unmuting need a connection. A mute made on one phone shows on the member's other phones the next time they open the app there. Every notification the app sends about that group is covered by one rule, in one place, and that rule decides which notifications a mute can never silence.

What is stored. One row per member and group: who, which group, and when the mute ends (empty means until they turn it back on). No reason, no history of earlier mutes, and nothing about any notification that was held back. The row belongs to the membership, so it can't outlive it.

So that a reminder the member set for themselves can always reach them, each task now records who last set its reminder. The database writes that, from whoever changed the reminder, whether in the app or through the assistant on their behalf, and nobody can write it directly. Like who created the task, the group can see it. If that person's account is erased, the task forgets who set its reminder. A reminder set before this change has no record of who set it, so it counts as set by somebody else until it is next changed.

Who can read it. Only that member. Other members, the group's admins and owner, and the assistant cannot read it. Whether somebody muted a group is a sign of how they engage with it, and the app never shows anybody how others engage (the ban self-assessment in this register). A member can't write the row directly either: one server function writes it, after checking that the caller is a member of the group, and works out when it ends.

When it ends. 8 hours is 8 hours of elapsed time. A week ends at the same time on the member's own clock seven days later, so a daylight-saving change in between doesn't move it by an hour. The phone's own time zone is used rather than the group's, because a mute belongs to the member and describes nothing the group shares. The end is shown on that clock too ("Muted until 6 pm"). On the phone, a muted group's feed countdown on the lock screen is removed, and it comes back when the mute is turned off or ends.

What a mute silences: chat messages, task and event notices, assignments and join requests, the daily catch-up (a muted group drops out of its count and names), reminders somebody else set, a profile's reminders sent to the adult who receives them, connection requests to the group, Mail Sifter suggestions, reported-photo notifications (the in-app list of reported photos is unaffected), and the baby feed countdown on the lock screen.

What a mute never silences:

The member is told these exceptions before they choose to mute: the choices sit below them, on the same sheet. Their own notification switches, and their phone's notification settings, still apply on top. Muting changes no switch, so unmuting never turns on something they had turned off.

Notifications already on their way. Each notification is checked against the mute at the moment it is sent, including a retry of one that failed earlier. A retry held back by a mute is removed from the delivery record, as if it had never been sent. The sender's app then sees what it sees for a member whose phone can't get notifications, rather than a failure it keeps offering to retry, which would tell them somebody had muted. Nothing records that it was held back.

Children can mute their own notifications, like any member. If a notice meant for a child's guardian about the child's safety is added later, it will be an exception.

How long it is kept. The row goes with the membership: when the member leaves or is removed, when the group is deleted, or when their account is erased. A departure and a mute at the same moment can't leave a row behind. An ended mute stops working at once and is deleted within 15 minutes.

Property Structural or conventional
Only the member reads their mute Structural: row-level security on the member's own rows, and no client can write the table
A mute can't outlive the membership Structural: the row is keyed to the membership and deleted with it
A reminder the member set themselves is told apart Structural: the database records who last set a task's reminder on every write from the app or the assistant, and overwrites any attempt to write it directly; an event reminder's author is fixed by row-level security
until is worked out by the server, and only members can mute Structural: the one write function checks membership and computes it
Every notification kind is mutable or an exception, and an unclassified kind is an error Structural in the database (the rule raises an error for a kind it does not know). Conventional, with a check over the source that fails the build until somebody reviews it: any new notification kind, any database statement that names the record of deliveries, any code file that sends a notification, any change to one of those files, and any notification the phone schedules itself. A name put together while the app runs would not be seen; nothing does that
Every sender asks before it sends Structural for the notices whose deliveries the database claims; for the four senders that send first and record after, each decision is a tested function, and the same check fails any change to those senders until it is reviewed
A mute never changes a preference Structural: the write function touches only the mute table

Residual risk we accept.

Re-read this section if a change proposes showing anybody a member's mute, adding a notification kind (the register check will fail until it is classified), or muting one of the exceptions above.

12. Creator notices and prompts

Approved by the founder, 26 October 2026. Tasks Option B, PR2 (HQ security check of Option B, conditions SC1–SC12), built to this description.

What a member can do. "Can't do this", from a task's sheet, offers:

Who is told, and how. Only the creator, once, in the Tasks tab's notice strip, and the person asked, for an ask. No push, no chat post, no badge count. A creator notice and an ask are group-readable, like every other task notice (§1: targeting routes attention, it never creates a private channel), and only their recipient is shown them. Setting one aside is the recipient's own row, readable by them alone.

The two prompts. Worked out on the creator's phone from facts the group already holds, never by a job on our server: "Nobody's taken ‘Fix the gate’ yet." (Ask someone / Skip / Keep it) once a task has had nobody on it for three days since it was added or last given back, and "Still needed?" (Keep / New date / Skip) once it is more than fourteen days overdue. Each comes once per task. Child accounts get neither (the 10 October amendment keeps child accounts free of interruptions nobody asked for); they do see notices a person sent them.

What is never shown or counted. No duration ("you've had this for 12 days"), no count of give-backs or skips, per person or at all, and History never filters or names who skipped a task. Nothing is reassigned, closed or skipped without a person's tap.

Children. A child account has full Tasks: a child can give back, ask someone else, skip a task they created, suggest closing one they didn't, and receive a creator notice or an ask. The protection is the same as §7's: nothing records that a child ignored or declined anything, and an adult cannot open any screen that shows it.

Encryption. Task words have been ordinary text protected by the database since 17 October 2026 (content-encryption v3), and the note follows the task: plain text on a group-readable row, capped by its column, never in a log. A member who would not write it on the task should not write it here, and the field sits on the same sheet as the task.

Property Structural or conventional
Only the creator (or an admin once they've left) skips a task; nothing else writes let_go_* Structural: the two functions and a trigger; who created a task is stamped by the database and can't be changed by a member; erasure alone clears who skipped it
Archived groups, routines, tallies and Deal cards are refused Structural: the functions check them
A skipped task never sends a reminder Structural: the reminder query excludes it
A suggestion never closes a task; keeping it is invisible to its author Structural: a separate row, settled by the recipient's own dismissal
Giving back or handing over changes only the caller Structural: one update over the row's current assignees
Notices and asks group-readable; dismissals owner-only; no direct writes Structural: grants and row-level security
The note is capped Structural: a column constraint
No push, no chat post Structural by absence: nothing in the functions reaches the delivery pipeline or the chat
The prompts are worked out on the phone, once per task, never for a child Conventional, tested; the "once" is a dismissal row
No duration, no count, no filter by who skipped Conventional, tested by copy and source checks
Tasks whose date has passed (PR2b, 26 October 2026): when a member opens the assistant, at most once a day, a card lists their own such tasks, and Today offers the same list on a tap ("Go through them"). Worked out on the phone from task dates, never written to the conversation, never sent to a model, never for a child unasked; "Keep" is the same once-only dismissal as "Still needed?" Conventional, tested; the once-a-day mark stays on the phone

Residual risk we accept. A member who looks at a task can see that a creator notice or an ask exists, because the rows are group-readable; that is the same coordination fact as an assignment, and the alternative is a private channel. The note is plain text, like the task it is about.

13. Sources

Primary: the Children's Online Privacy Code exposure draft, ss 10, 14(3)(b), 38, 39; the Online Safety (Age-Restricted Social Media Platforms) Rules 2025, s 4A(5)(a), read alongside the ban self-assessment in this register (which is why sender-visible seen state is refused outright rather than weighed).

In repo: lib/detailsRequests.ts (the existing household fill-in card whose machinery and prefix discipline this design extends); lib/pendingActions.ts (badgeCount and seen references); supabase/migrations/20260905123533_action_stacks_audience.sql and 20260905135802_close_action_stacks_insert_hole.sql (the audience column and the insert predicate the recipient model builds on); supabase/functions/dispatch-task-reminders/reminders.ts (lockedReminderBody, the push-title rule); components/Chat/__tests__/noFeedbackFeatures.test.ts (the scan to extend); store/__tests__/detailsRequestPrefix.test.ts (the card-conflation pin); our internal engineering rules on RSVPs versus proposals, on the app never deciding to interrupt anyone, and on a declined handoff not being recorded; docs/pia/2026-09-ban-self-assessment.md §5.3; docs/privacy_posture.md. For §11: supabase/migrations/20261021181115_group_notification_mutes.sql (the table, the write function, the rule and the claim checks); supabase/functions/_shared/mutes.ts (the senders that send first); agent-server/checks/genericPushes.check.ts (the register of every notification kind and its class); __tests__/group_notification_mutes_rls.test.ts. For §12: supabase/migrations/20261025221527_tasks_cant_do_this_let_go_and_creator_notices.sql (the columns, the guard, the three tables and the functions); lib/taskCantDo.ts (the copy, the choices and the two prompts); __tests__/tasks_cant_do_rls.test.ts; lib/__tests__/taskCantDo.test.ts; for the PR2b row, lib/pastDateTasks.ts and lib/__tests__/pastDateTasks.test.ts.