fix(calendar): export VTODO CREATED from task creation time - #1653
seonghobae wants to merge 5 commits into
Conversation
generate_ics_from_task serialized only DTSTAMP (updated_at), so calendar clients could not distinguish task creation from modification. Emit iCalendar CREATED from CalendarTask.created_at per RFC 5545 and cover it with a parsed iCalendar regression.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe ICS generator now validates ChangesCalendar timestamp normalization
Priority: ⬇️ Low Estimated code review effort: 2 (Simple) | ~15 minutes Merge Risk: ⚪ Minimal · up to Calendar exports now serialize change-management timestamps in UTC and reject invalid naive values, with no remaining actionable merge risk. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review Please review exact |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
base='042b0c70531b229af3acbd0421a2f23098d848b3'
head='db74bb189817345fc9dbe1db038e5e787e5d9a45'
echo '== Commit relationship =='
git merge-base --is-ancestor "$base" "$head" && echo 'base is an ancestor of head'
git diff --check "$base..$head"
git diff --name-status "$base..$head"
git diff --stat "$base..$head"
git diff --find-renames --find-copies "$base..$head"
echo '== Candidate file maps =='
fd -t f 'calendar_sync\.py$|calendar\.py$' backend | sort | while IFS= read -r f; do
echo "--- $f"
ast-grep outline "$f" --items all --match 'generate_ics_from_task|CalendarTask' --view expanded || true
done
echo '== Relevant implementation, test, and caller contexts =='
rg -n -C 12 --glob '*.py' \
'def generate_ics_from_task\b|class CalendarTask\b|created_at\s*=|updated_at\s*=|Todo\s*\(' \
backend
echo '== Exact PR and issue metadata =='
gh pr view 1653 --repo ContextualWisdomLab/naruon \
--json number,title,body,state,isDraft,baseRefOid,headRefOid,url,closingIssuesReferences
echo '--- Issue 1086 ---'
gh issue view 1086 --repo ContextualWisdomLab/naruon \
--json number,title,state,body,url,closedByPullRequestsReferences
echo '--- Issue 1195 ---'
gh issue view 1195 --repo ContextualWisdomLab/naruon \
--json number,title,state,body,url,closedByPullRequestsReferencesLength of output: 156157 🏁 Script executed: #!/bin/bash
set -euo pipefail
base='042b0c70531b229af3acbd0421a2f23098d848b3'
head='db74bb189817345fc9dbe1db038e5e787e5d9a45'
echo '== Exact-range commit messages and issue-keyword references =='
git log --format='%H%n%B%n---' "$base..$head"
git log --format='%H %s' "$base..$head" | rg -n -i '(close[sd]?|fix(e[sd])?|resolve[sd]?|`#1086`|`#1195`)' || true
echo '== All CalendarTask construction and calendar export call sites =='
rg -n -U -C 8 --glob '*.py' \
'(CalendarTask\s*\(|generate_ics_from_task\s*\()' backend
echo '== Calendar dependency declaration and installed serializer source, if available =='
rg -n -C 3 --glob 'requirements*.txt' --glob 'pyproject.toml' --glob 'poetry.lock' --glob 'uv.lock' \
'(^|[-_ ])icalendar([<>=!~ ].*|$)' .
python - <<'PY'
from pathlib import Path
candidates = []
for root in (Path('.'), Path('/usr/local/lib'), Path('/usr/lib')):
if root.exists():
candidates.extend(root.rglob('prop.py'))
for path in candidates:
if 'icalendar' in str(path) and path.is_file():
print(f'--- {path}')
text = path.read_text(errors='replace')
for term in ('class vDDDTypes', 'def to_ical'):
start = text.find(term)
if start >= 0:
print(text[start:start+2800])
break
PY
echo '== Pull request references and issue timeline events =='
gh api "repos/ContextualWisdomLab/naruon/issues/1653/timeline?per_page=100" \
-H 'Accept: application/vnd.github+json' \
--jq '.[] | select(.event == "cross-referenced" or .event == "connected" or .event == "closed" or .event == "referenced") | {event,created_at,source:(.source.issue.number // .source.commit.sha // null),commit_id:(.commit_id // null)}' || true
gh api "repos/ContextualWisdomLab/naruon/issues/1086/timeline?per_page=100" \
-H 'Accept: application/vnd.github+json' \
--jq '.[] | select(.event == "cross-referenced" or .event == "closed" or .event == "referenced") | {event,created_at,source:(.source.issue.number // .source.commit.sha // null),commit_id:(.commit_id // null)}' || trueLength of output: 16034
However, GitHub currently lists ✅ Action performedReview finished.
|
|
@coderabbitai review Fresh exact-range review requested for canonical base |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
base='17a7618eda2b212b691f08fa936e042b34258fc9'
head='f2f689c04b84b2eac4e36ff79c7343266885dc18'
repo='ContextualWisdomLab/naruon'
echo '== Exact range integrity and effective delta =='
git merge-base --is-ancestor "$base" "$head"
echo 'base is an ancestor of head'
git log --format='%H%n%B%n---' "$base..$head"
git diff --check "$base..$head"
git diff --name-status "$base..$head"
git diff --stat "$base..$head"
git diff --find-renames --find-copies "$base..$head"
git diff --unified=80 "$base..$head" -- backend/services/calendar_sync.py backend/tests/test_calendar_sync.py || true
echo '== Candidate file maps =='
fd -t f -a 'calendar_sync\.py$|models?\.py$|requirements.*\.txt$|pyproject\.toml$|poetry\.lock$|uv\.lock$' . \
| sort \
| while IFS= read -r file; do
echo "--- $file"
ast-grep outline "$file" --items all \
--match 'generate_ics_from_task|CalendarTask|Todo|datetime|icalendar' \
--view expanded || true
done
echo '== Timestamp construction, export, and test contexts =='
rg -n -U -C 15 --glob '*.py' \
'(def generate_ics_from_task\s*\(|class CalendarTask\b|CalendarTask\s*\(|generate_ics_from_task\s*\(|created_at\s*=|updated_at\s*=|\.add\(\s*["'\''](?:CREATED|DTSTAMP)["'\''])' \
backend || true
echo '== Calendar serialization dependency declarations =='
rg -n -C 4 \
--glob 'requirements*.txt' --glob 'pyproject.toml' --glob 'poetry.lock' --glob 'uv.lock' \
'(^|[-_[:space:]])icalendar([<>=!~[:space:]].*|$)' . || true
echo '== Installed icalendar DATE-TIME serialization and parsing source, if present =='
python - <<'PY'
from pathlib import Path
roots = [Path('/usr/local/lib'), Path('/usr/lib')]
for root in roots:
if not root.exists():
continue
for path in root.rglob('prop.py'):
if 'icalendar' not in str(path).lower():
continue
text = path.read_text(errors='replace')
if 'class vDDDTypes' not in text:
continue
print(f'--- {path}')
start = text.index('class vDDDTypes')
print(text[start:start + 6500])
PY
echo '== PR metadata and issue-reference state =='
gh pr view 1653 --repo "$repo" \
--json number,state,isDraft,title,body,baseRefOid,headRefOid,closingIssuesReferences,url
gh api "repos/$repo/issues/1653/timeline?per_page=100" \
-H 'Accept: application/vnd.github+json' \
--jq '.[] | select(.event == "cross-referenced" or .event == "connected" or .event == "referenced" or .event == "closed") | {event, created_at, source: (.source.issue.number // .source.commit.sha // null)}' || trueLength of output: 203004 🤖 web_search executed:
Length of output: 13472
I found no code findings.
Runtime tests were not executed in this review environment. ✅ Action performedReview finished.
|
Current authority — 2026-09-11
develop@042b0c70531b229af3acbd0421a2f23098d848b3#1623@17a7618eda2b212b691f08fa936e042b34258fc9db74bb189817345fc9dbe1db038e5e787e5d9a45443d13e1446c8d7140e889a8bcbcf4c2b616f3bde74537faa3cf39e7f628dbc5be4d6adefdbe800e184446b5a2c5e797e62ba5aa6dd5ce65bbc691baf2f689c04b84b2eac4e36ff79c7343266885dc18Finding and repair
generate_ics_from_task()carriedCalendarTask.created_atbut discarded it when generating VTODO, so downstream calendar clients receivedDTSTAMPwithout the calendar-store creation timestamp. The original repair added standardCREATEDand a parsed regression.Fresh standards review found a second invariant in the same boundary. RFC 5545 §3.8.7.1 requires
CREATEDto be UTC and §3.8.7.2 requiresDTSTAMPon VTODO and likewise requires UTC. Passing arbitrarydatetimeobjects directly to the serializer left that requirement implicit and could allow non-UTC or host-dependent naive values.Source-order RED
e74537f...requires offset-aware non-UTC inputs to serialize as UTCZvalues and requires naivecreated_at/updated_atvalues to fail closed. Causal fix184446b...restoresCREATEDand routes both change-management timestamps through one UTC normalization boundary. Naive values raise a field-specificValueErrorinstead of acquiring local-machine timezone meaning.DUEis intentionally unchanged because RFC 5545 permits other DATE-TIME forms for that property.The production writeback caller in
backend/api/calendar.pyalready constructs both values withdatetime.datetime.now(datetime.timezone.utc), so the stricter serializer boundary preserves the live path.Owner topology
The direct-develop predecessor inherited Security Scan failures from the stale frontend dependency tree. That source is not owned by a calendar serializer lane.
443d13e...preservesdb74bb1...as first-parent provenance, adopts current #1623 as second parent, and starts from #1623's exact tree. The calendar source/test are then restored with the stronger RFC contract and doctoring; no dependency, lockfile, workflow, or security-owner source is copied here.Fresh compare over #1623 is ahead-only / behind 0 and limited to exactly three files:
backend/services/calendar_sync.py,backend/tests/test_calendar_sync.py, anddocs/doctoring/calendar-vtodo-change-timestamps.md.Evidence boundary
Pre-retarget direct-develop runs do not transfer. Current exact
f2f689c...on feature base17a7618...still has zero PR-triggered repository workflow runs at the latest lookup. This remains a live canary for the stacked-PR executable-evidence defect owned byContextualWisdomLab/.github#2073; do not retarget todevelop, push a dummy commit, copy workflow source, or synthesize a status.CodeRabbit submitted formal
APPROVEDat2026-09-11T02:51:26Z, after exactf2f689c...was created, so the independent current-head review lane is satisfied for the unchanged head. That approval does not substitute for executable evidence or #1623 prerequisite integration.The UTC RED commit is source-order evidence, not claimed as a terminal hosted RED.
Standards traceability
docs/doctoring/calendar-vtodo-change-timestamps.mdrecords the problem, constraint, alternatives, RED/fix lineage, acceptance boundary, and APA 7th citation for RFC 5545:Desruisseaux, B. (2009). Internet Calendaring and Scheduling Core Object Specification (iCalendar) (RFC 5545). Internet Engineering Task Force. https://doi.org/10.17487/RFC5545
Keep Draft until #1623 is protected-integrated or canonical stacked verification produces an exact current-base/head executable receipt with then-live required contexts terminal-success. No force push, destructive rebase, stale-evidence transfer, self-approval, dependency-owner duplication, or gate weakening.