style(13-03): apply Prettier formatting across repo
Mechanical reformat — no logic changes. 398 files changed, 19125 insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc (singleQuote:true, semi:true, tabWidth:2, trailingComma:all, printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
@@ -14,29 +14,29 @@ autonomous: true
|
||||
requirements: []
|
||||
must_haves:
|
||||
truths:
|
||||
- "Scope fence (D-01/D-02): recurrence bounding only — NO VALARM/reminder serialization (999.4) is added to the write path; reminders are deferred to milestone 1.1"
|
||||
- "A recurring series can be bounded by a repeat-until date (RRULE UNTIL) or an occurrence count (RRULE COUNT) (D-06)"
|
||||
- "All-day UNTIL serializes as a DATE (YYYYMMDD); timed UNTIL serializes as a UTC DATETIME (YYYYMMDDT235959Z) (D-06, RFC 5545 §3.3.10)"
|
||||
- 'Scope fence (D-01/D-02): recurrence bounding only — NO VALARM/reminder serialization (999.4) is added to the write path; reminders are deferred to milestone 1.1'
|
||||
- 'A recurring series can be bounded by a repeat-until date (RRULE UNTIL) or an occurrence count (RRULE COUNT) (D-06)'
|
||||
- 'All-day UNTIL serializes as a DATE (YYYYMMDD); timed UNTIL serializes as a UTC DATETIME (YYYYMMDDT235959Z) (D-06, RFC 5545 §3.3.10)'
|
||||
- "A 'daily' frequency selection persists as FREQ=DAILY end-to-end through the outbox (D-07)"
|
||||
artifacts:
|
||||
- path: "apps/api/src/broker/outboxWorker.ts"
|
||||
provides: "assembleRruleString helper + UNTIL/COUNT assembly wired into the write payload"
|
||||
contains: "assembleRruleString"
|
||||
- path: "apps/api/src/routes/events.ts"
|
||||
provides: "eventFieldsSchema accepts recurrenceUntil + recurrenceCount"
|
||||
contains: "recurrenceUntil"
|
||||
- path: "apps/api/tests/broker/vevent.test.ts"
|
||||
provides: "UNTIL-DATE, UNTIL-DATETIME, COUNT serialization assertions"
|
||||
contains: "COUNT=5"
|
||||
- path: 'apps/api/src/broker/outboxWorker.ts'
|
||||
provides: 'assembleRruleString helper + UNTIL/COUNT assembly wired into the write payload'
|
||||
contains: 'assembleRruleString'
|
||||
- path: 'apps/api/src/routes/events.ts'
|
||||
provides: 'eventFieldsSchema accepts recurrenceUntil + recurrenceCount'
|
||||
contains: 'recurrenceUntil'
|
||||
- path: 'apps/api/tests/broker/vevent.test.ts'
|
||||
provides: 'UNTIL-DATE, UNTIL-DATETIME, COUNT serialization assertions'
|
||||
contains: 'COUNT=5'
|
||||
key_links:
|
||||
- from: "apps/api/src/broker/outboxWorker.ts"
|
||||
to: "apps/api/src/broker/vevent.ts"
|
||||
via: "assembled rruleString passed to buildVeventString"
|
||||
pattern: "assembleRruleString|rruleString"
|
||||
- from: "apps/api/src/routes/events.ts"
|
||||
to: "apps/api/src/broker/outboxWorker.ts"
|
||||
via: "recurrenceUntil/recurrenceCount in enqueued payload"
|
||||
pattern: "recurrenceUntil|recurrenceCount"
|
||||
- from: 'apps/api/src/broker/outboxWorker.ts'
|
||||
to: 'apps/api/src/broker/vevent.ts'
|
||||
via: 'assembled rruleString passed to buildVeventString'
|
||||
pattern: 'assembleRruleString|rruleString'
|
||||
- from: 'apps/api/src/routes/events.ts'
|
||||
to: 'apps/api/src/broker/outboxWorker.ts'
|
||||
via: 'recurrenceUntil/recurrenceCount in enqueued payload'
|
||||
pattern: 'recurrenceUntil|recurrenceCount'
|
||||
---
|
||||
|
||||
<objective>
|
||||
@@ -63,10 +63,11 @@ Output: `assembleRruleString` in `outboxWorker.ts`, extended Zod schema in `even
|
||||
|
||||
<artifacts_this_plan_produces>
|
||||
NEW symbols introduced here (exclude from drift/convergence checks):
|
||||
|
||||
- `assembleRruleString(basePreset, until?, count?, allDay?): string` in `apps/api/src/broker/outboxWorker.ts`
|
||||
- Two new optional fields on `eventFieldsSchema` (`events.ts`) and `outboxPayloadSchema` (`outboxWorker.ts`): `recurrenceUntil` ('YYYY-MM-DD'), `recurrenceCount` (int ≥ 1)
|
||||
- New test cases in `vevent.test.ts` (COUNT, UNTIL DATE, UNTIL DATETIME) and `outboxWorker.test.ts` (FREQ-persistence regression, bound-assembly)
|
||||
</artifacts_this_plan_produces>
|
||||
</artifacts_this_plan_produces>
|
||||
|
||||
<tasks>
|
||||
|
||||
@@ -133,19 +134,21 @@ NEW symbols introduced here (exclude from drift/convergence checks):
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| Boundary | Description |
|
||||
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| client → API (POST/PATCH /api/events) | `recurrenceUntil` / `recurrenceCount` are new untrusted inputs crossing into the write path and ultimately into an ICS RRULE string sent to Fastmail CalDAV. |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-06-02 | Tampering | recurrenceUntil/recurrenceCount → RRULE string (events.ts, outboxWorker.ts) | mitigate | Zod `z.string().max(10)` on `recurrenceUntil` + `z.number().int().min(1)` on `recurrenceCount` at the route boundary; `assembleRruleString` only emits digits from a `replace(/-/g,'')` of a length-bounded string; final string is re-parsed by `ICAL.Recur.fromString` which rejects malformed RRULE — no raw passthrough to the ICS. (V5 Input Validation, ASVS L1.) |
|
||||
| T-06-02b | Tampering | RRULE injection via crafted until value | mitigate | The `.replace(/-/g,'')` plus the fixed `;UNTIL=`/`;COUNT=` templates prevent injecting extra `;`-delimited RRULE parts; `ICAL.Recur.fromString` sanitizes via parse. A date that is not `YYYY-MM-DD` produces a non-date string that ical.js rejects or normalizes — fails closed (event enqueue errors), no silent corruption. |
|
||||
| T-06-02-SC | Tampering | npm installs | accept | No package installs in this plan (RESEARCH: Package Legitimacy Audit not applicable — zero new deps). |
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
| ---------- | --------- | --------------------------------------------------------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| T-06-02 | Tampering | recurrenceUntil/recurrenceCount → RRULE string (events.ts, outboxWorker.ts) | mitigate | Zod `z.string().max(10)` on `recurrenceUntil` + `z.number().int().min(1)` on `recurrenceCount` at the route boundary; `assembleRruleString` only emits digits from a `replace(/-/g,'')` of a length-bounded string; final string is re-parsed by `ICAL.Recur.fromString` which rejects malformed RRULE — no raw passthrough to the ICS. (V5 Input Validation, ASVS L1.) |
|
||||
| T-06-02b | Tampering | RRULE injection via crafted until value | mitigate | The `.replace(/-/g,'')` plus the fixed `;UNTIL=`/`;COUNT=` templates prevent injecting extra `;`-delimited RRULE parts; `ICAL.Recur.fromString` sanitizes via parse. A date that is not `YYYY-MM-DD` produces a non-date string that ical.js rejects or normalizes — fails closed (event enqueue errors), no silent corruption. |
|
||||
| T-06-02-SC | Tampering | npm installs | accept | No package installs in this plan (RESEARCH: Package Legitimacy Audit not applicable — zero new deps). |
|
||||
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
@@ -155,10 +158,11 @@ NEW symbols introduced here (exclude from drift/convergence checks):
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
|
||||
- D-06: bounded recurrence serializes correctly, value-type-matched to DTSTART.
|
||||
- D-07: daily→FREQ=DAILY regression is locked by an automated test.
|
||||
- API contract (`recurrenceUntil`/`recurrenceCount`) is live for Plan 06's UI to drive.
|
||||
</success_criteria>
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
Create `.planning/phases/06-ux-polish/06-02-SUMMARY.md` when done (RED/GREEN notes + commits; note any Fastmail UNTIL value-type observation for the verify step).
|
||||
|
||||
Reference in New Issue
Block a user