Skip to content

[P0 Review Gap] Replace user-entered weekly counts with authoritative Planning/Habit projections #263

Open

Description

@seonghobae

Buyer-visible failure

The current Weekly Review workspace still asks the user to type plannedItemCount, completedItemCount, and habitCompletionCount and persists those values as Review completion evidence. That is useful as an explicit self-report, but it cannot satisfy LifeOS's defining Review contract: the weekly review must show authoritative, read-only evidence from Planning and Habit for what was actually planned, completed, stalled, overdue, scheduled, and adhered to.

This is not a UI-copy problem. It is a missing cross-bounded-context read-model contract.

Fresh source evidence — 2026-09-10

Protected LifeOS main@193a87ef54c3fe6dcda4755bce4d6bc81e3a0297 is the shipped domain authority.

  • Planning exposes tenant-scoped Goal/Project/Task CRUD/list boundaries and a durable Today aggregate. Goal and Project currently carry only identity/title/createdAt; Task carries identity/title/status/createdAt. There is not enough producer-owned temporal evidence to label a goal "stalled", a project "inactive", or a task "overdue" without inventing semantics.
  • Habit already owns recurrence, dated occurrences, Today status, completion mutation, and per-habit completion history.
  • Review persistence accepts plannedItemCount, completedItemCount, and habitCompletionCount inside the completion command and binds them into the immutable payload digest.
  • Draft Weekly Review workspace feat(web): add durable Weekly Review workspace #234 currently collects those three counts from browser form fields. Its own PR contract correctly says these are not authoritative Planning/Habit projections and does not claim [P0 Product Gap] Complete the authenticated Goal → Project → Task → Habit → Review workspace #209 complete.

Therefore no consumer may infer that the existing three integers are system-measured productivity/adherence evidence.

Canonical architecture

LifeOS remains server-backed modular MSA. Planning owns Planning truth; Habit owns Habit truth; Review owns immutable Review ritual/completion truth. No cross-service SQL, source copy, browser-side joins that become authority, or second persistence owner.

The preferred integration is producer-owned bounded read models composed by the authenticated web/BFF boundary:

  1. Planning exposes a purpose-bound/versioned Weekly Review projection only after the underlying domain evidence is capable of supporting the requested concepts. If overdue/stalled/inactive semantics require due date, completion/update activity, milestone, or other temporal domain evidence, add those as Planning-owned concepts with migrations/invariants first rather than inferring them from createdAt.
  2. Habit exposes or reuses a bounded period projection derived from recurrence/occurrence/completion truth. The denominator is scheduled opportunities in the requested period; the numerator is exact accepted completions. Rule changes must not rewrite historical opportunities.
  3. The authenticated BFF derives workspace/user authority from Identity, signs exact method/path requests to each producer, validates scope/schema/period/as-of evidence, and composes only browser-safe read data. Browser input may select a review period but never supply workspace authority or authoritative aggregate counts.
  4. Review completion may retain an optional explicit self-report only if it is named and modeled as self-report. System projection values must never be copied into Review persistence as if Review owned them unless an ADR establishes a snapshot/provenance requirement and stores exact producer/version/as-of provenance.

Projection evidence contract

Every producer projection must include enough typed evidence to prevent denominator drift and stale attribution. At minimum:

  • exact local review period and authoritative timezone source;
  • asOf canonical instant and projection schema/version;
  • bounded counts with explicit numerator/denominator semantics;
  • producer identity and any revision/version needed to detect stale evidence;
  • no workspace/user identifier in browser output unless the product task requires it;
  • deterministic ordering and bounded collections where item-level evidence is exposed.

Planning metrics may include only concepts supported by current domain truth. stalled, inactive, overdue, schedule realism, and completion rates are forbidden until their estimand/threshold and source fields are explicitly defined. Habit adherence must retain scheduled-opportunity denominator and period; do not convert completion counts alone into an adherence rate.

RED acceptance

A current test must prove the existing Weekly Review path can be populated with browser-authored aggregate counts even when Planning/Habit evidence disagrees or is absent. The test should fail once the product requires producer-owned projections for those displayed metrics.

Additional hostile cases must cover cross-workspace producer evidence, wrong period/timezone, duplicate IDs, stale revisions/as-of evidence, malformed or oversized payloads, partial producer failure, impossible numerator > denominator, and a Habit rule change inside the review period.

GREEN acceptance

  • Weekly Review loads authenticated Planning/Habit projections without browser-supplied authority or cross-service SQL.
  • User-entered fields are removed for metrics represented as system evidence, or distinctly labeled/persisted as self-report if retained.
  • Projection semantics preserve actual period, timezone, numerator, denominator, as-of time and provenance.
  • Partial/unavailable producer evidence is shown as unavailable, never silently zero.
  • Existing immutable Review history remains readable; migration/version compatibility is explicit if the completion schema changes.
  • Current-head unit/contract/PostgreSQL integration/E2E cover normal, loading, empty, producer-error, auth-denied, stale/conflict and offline/recovery states.
  • Applicable buyer-path API p95 is measured against 20 ms without warm-cache/sample exclusions; if producer-side aggregation is required to avoid N+1 fan-out, profile and implement it at the owning service.
  • Owned production statement/branch/function/line, edge-case, and production-docstring coverage remain 100%.
  • PRD/TRD/Architecture/UML/ADR/Threat Model/Test Strategy/Operability/CHANGELOG and docs/product-technical-gap-baseline.md are code-current.
  • [P0 Product Gap] Complete the authenticated Goal → Project → Task → Habit → Review workspace #209 remains open until the release artifact proves the full authenticated Goal → Project → Task → Habit → Today → Review journey.

Non-goals

  • inventing psychological or productivity scores from partial observations;
  • treating createdAt alone as inactivity/stall evidence;
  • universal habit-formation thresholds;
  • autonomous AI mutation of plans/habits;
  • browser aggregation becoming domain authority;
  • reading Planning or Habit database tables from Review or Web.

Refs #209, #234.

Activity

  1. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Producer-side execution started in Draft #264 from protected main@193a87ef54c3fe6dcda4755bce4d6bc81e3a0297.

    Hosted RED was obtained on exact 9fb26d48c47f5f85c3468b45abe3f33a082e0dd0: CI merge-compatibility constructed the clean current-main integration tree and then failed @life-os/habit-service#typecheck because HabitService did not accept the projection clock and had no projectReviewWeek method. This is the intended missing-capability RED, not a manual harness or infrastructure failure.

    The current repair head is e82165e9b526599b9f57fefc977fd63f3c7772d2. It keeps Habit as producer/owner, derives the seven-day denominator from existing recurrence truth, counts distinct scheduled dates with accepted completion evidence, retains each habit timezone, fails closed above 100 habits, rejects non-Monday periods, and emits versioned life-os.habit-review-projection.v1 evidence with canonical server asOf. It deliberately labels the period basis habit-local-date; it does not invent the still-missing workspace-timezone authority or Planning stalled/inactive/overdue semantics.

    This is a domain projection slice only. HTTP/BFF composition, Review self-report separation, Planning projection, workspace-timezone authority, and product UI remain open acceptance under this issue.

  2. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Fresh #264 producer-side repair evidence: review of 55074602ca4fd7b75e0346a1b503bfb16ca56e10 found that the initial Habit Weekly Review projection still performed one unbounded listHabits() read plus one full-history listCompletions() read per habit. That was a real violation of this issue's bounded read-model / no-N+1 acceptance.

    PR #264 now has ordinary descendants through 43e54a41bc1dd79371501456131d4bfeb49aefd6. A regression commit requires the PostgreSQL projection seam to issue one statement. The production repair uses a Habit-owned bounded read model: candidate habits are capped at 101 to prove the 100-item ceiling; completion evidence is limited to the exact seven local dates and deduplicated by (habit, scheduledLocalDate) inside the SQL statement; returned rows are revalidated for tenant, period, cardinality and schedule consistency by the adapter/service. General completion-history APIs remain unchanged and no Review/Web cross-service SQL was introduced.

    This is still Draft/unshipped. Current-head repository CI/performance evidence is not yet available, so the p95≤20 ms acceptance remains open. Planning evidence, authenticated BFF composition, partial-producer failure UX, and removal/distinction of browser-authored Review counts also remain open; #263 should not close.

  3. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Habit producer slice progress is now source-backed but still unshipped. PR #264 current exact f116d1af791eb248de46295f88ef49f1eeb48454 owns a bounded Monday-through-Sunday Review projection over Habit truth: one tenant-scoped persistence read, maximum 100 habits with overflow fail-closed evidence, completion evidence bounded to the exact period and deduplicated by scheduled local date, per-habit recurrence/timezone denominator calculation, and server asOf.

    A fresh hostile-case review also found that duplicate Habit identities returned by persistence could duplicate per-habit rows and scheduled-opportunity denominators. Regression adda5d7c0d71ad2f85515b3f2b85314213311736 now injects that corruption, and current source rejects it when Habit-ID Set cardinality differs from the evidence collection. Bounded repair run 34467502684 / job 102839410118 completed typecheck, the duplicate-evidence projection regression, Review evidence-contract tests, PostgreSQL Review projection tests, full Habit tests and build before self-retiring its temporary writer and publishing the current candidate.

    This does not complete #263. Planning still lacks producer-owned temporal fields/estimands needed to define stalled/inactive/overdue without inference from createdAt; authenticated BFF composition, partial-producer unavailable/error behavior, removal or explicit self-report relabeling of browser-entered aggregate counts, locale/a11y/E2E delivery, current docs/traceability and p95≤20 ms buyer-path measurement remain open. #264 stays Draft and independent of mutable #249 until the shared foundation reaches protected main and can be adopted by ordinary non-force ancestry.

  4. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Habit producer slice advanced on #264 with a new asOf evidence-time fence. Hosted regression proved the old adapter accepted a completion recorded after the timestamp the projection would advertise; exact repair now captures one canonical asOf before the read, passes it through the Habit-owned repository contract, filters Habit createdAt and completion recordedAt against that instant in both InMemory and PostgreSQL adapters, and returns the same instant. Self-retiring writer run 34470591750 / job 102849317958 completed frozen install, RED proof, repair, formatting, Habit typecheck, focused Review regressions, full Habit tests and build, then removed itself and published 93c738f8ae5c931e9619dd1fec85dcc1da3e3fea.

    This only closes the evidence-time consistency gap. #263 remains open: current Habit definitions are not yet durable historical revisions, so recurrence/title/timezone changes within a reviewed period still lack producer-owned revision/provenance semantics. Planning temporal truth, authenticated BFF composition, unavailable-vs-zero producer failure handling, browser self-report/system-count cleanup, locale/a11y/E2E, traceability and measured p95 remain outstanding.

  5. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Habit producer update from #264 current exact 3d883e4811c8b857ea75df1da96737c732f217c1:

    Fresh review adopted the intervening Review HTTP work rather than treating concurrent ordinary descendants as a race. Two authority defects were repaired. d659042a... had copied still-mutable #249 AppGuardrail formatting into the Habit slice; 7e247c56... restores that file byte-for-byte to protected main, so #264 again contains only Habit-owned source/test delta and waits for #249 through protected ancestry instead of source copying.

    More importantly, the initial v2 Review HMAC was given { method: 'GET', path: '/v1/habits/review-projection' } by the controller itself rather than binding authorization to the server-observed request target. Regression 6b0fdf0... requires the canonical route to work and rejects trailing-slash, duplicate-slash, percent-encoded-slash and wrong-method aliases before Habit domain access. Hosted run 34478257089 / job 102874277431 produced the intended RED. The repair now takes Nest @Req(), derives the binding from raw originalUrl/url plus the observed method before route normalization, and keeps periodStartDate as separate typed domain input.

    After a formatting RED and a CommonJS/module-target harness RCA (import.meta was invalid under the Habit service TypeScript target), self-retiring writer input 25e0bf76... completed run 34479145260 / job 102877254682 SUCCESS: frozen install, repository Prettier, Habit typecheck, focused Review HTTP 6/6, full Habit suite 91 passed + 9 environment-dependent skipped, build, bounded diff, workflow retirement and ordinary publication all passed. The temporary workflow is absent from the published candidate.

    This advances only the Habit producer/transport slice. #263 remains open for producer-owned Habit definition revision/provenance across rule changes, Planning temporal truth for stalled/inactive/overdue, authenticated Review/BFF composition, unavailable-vs-zero partial failure semantics, removal/relabeling of browser-entered system counts, locale/a11y/E2E/traceability, 100% owned production quality evidence, and real buyer-path p95 <= 20 ms. No central Security/CodeQL or #249 prerequisite is suppressed locally.

  6. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Habit producer slice update from #264: fresh current-head review found that schemaVersion + asOf did not satisfy this issue's producer/revision evidence contract. Regression-only 08f7ca1ef832ffae32568294d835d0897ee48f38 added producer/revision expectations and produced a hosted reality RED in CI 34480819651 / merge-compatibility job 102882872818: the clean current-main integration tree failed Habit typecheck because HabitReviewWeekProjection lacked producer and projectionRevision.

    Ordinary descendants now end at exact f28b0ea4d47364d75c1200ee5de0aed17c653b45. Habit emits producer: 'habit' plus a deterministic sha256:<64hex> revision over the normalized semantic projection while keeping asOf separate freshness metadata; unchanged semantic evidence is stable and accepted completion evidence changes the revision. The HTTP projection fixture carries the same contract. Current exact CI merge-compatibility is GREEN through current-main integration typecheck/test/build, and browser-acceptance/today-concurrency/compose-runtime are also GREEN. Root validate remains RED only on protected-main .github/workflows/appguardrail.yml formatting, which stays a #249-owned prerequisite rather than being copied into this Habit slice; SAST and AppGuardrail are GREEN, while Security/Commercial Readiness/CodeQL remain separate central/prerequisite lanes.

    This does not satisfy historical Habit-definition revision authority. The digest identifies the semantic projection returned for a period; recurrence/title/timezone history is still absent from durable Habit persistence, so historical rule-change semantics remain open here alongside Planning temporal truth, partial-failure composition, browser-count authority, locale/a11y/E2E/traceability, and measured buyer-path p95.

  7. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Habit producer follow-up is now stronger on deterministic provenance. Fresh review found that projectionRevision was computed after sorting entries with ambient String.prototype.localeCompare(), making the serialized projection—and therefore SHA-256 revision—dependent on runtime locale/ICU. Bounded run 34487743551 / job 102906260494 established the hostile RED under en_US.UTF-8 (['z','ä'] emitted as ['ä','z']), replaced that ordering with a locale-independent code-unit comparator for title + Habit ID, then passed the regression under sv_SE.UTF-8, Habit typecheck, full Habit tests (93 passed; 9 existing environment-gated integration tests skipped), build, formatting, and diff hygiene. The temporary writer self-retired before publishing 339abf0e...; same-tree ordinary descendant e07e3460598ed6a9cc3601ed30d2b92273ef5535 now carries the normal exact-head checks. This closes the ambient-locale reproducibility gap in the Habit projection fingerprint, but not historical Habit-definition revision authority. Planning temporal truth, unavailable-vs-zero BFF composition, historical rule semantics, UI/E2E/locale/a11y, and measured buyer-path latency remain open.

  8. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Fresh Planning-authority review found a narrower prerequisite before any Weekly Review task-completion metric can be authoritative. Protected main@193a87ef54c3fe6dcda4755bce4d6bc81e3a0297 already has planning.tasks.completed_at, but Task/PostgresPlanningRepository do not expose it and migration 0001 does not bind it to status or created_at. The database can therefore represent done + NULL completed_at, todo + non-NULL completed_at, or completion before creation. No existing open Planning-owned Review/temporal PR was found. Draft #266 now owns the first bounded prerequisite: establish a forward service-owned completion-state/chronology invariant test-first, without inventing overdue/stalled/inactive semantics. This remains a foundation only; explicit completion transition, producer projection, BFF composition, unavailable-vs-zero semantics, historical/revision evidence, E2E and p95 remain open.

  9. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Planning temporal foundation update from #266: durable task completion chronology is now staged and reality-tested instead of being treated as an application-only convention. planning.tasks gets tasks_completion_state_check in 0005 with NOT VALID, so contradictory new/changed rows already fail while the initial historical-table scan is avoided; 0006 performs the separate historical VALIDATE CONSTRAINT boundary and deployment remains fail closed until validation succeeds. Regression 164ae03a2e8ccfa73fa03bc694ad76cf38f9b1e7 produced hosted RED on canary run 34497919705 / job 102941002188 before staging existed. After the causal migration split and documentation/recovery update, exact PostgreSQL canary run 34498191009 / job 102941944243 is GREEN. The temporary canary was then removed in ordinary descendant 1de871ea86fef454639708f1044c40246ca1e9f4.

    This does not complete Weekly Review semantics. Planning still needs an application/HTTP completion transition that atomically owns status + completed_at, then producer-owned due/completion/status-transition/activity chronology sufficient to define overdue/stalled/inactive without inference from current state. Only after that should #263 add the bounded version/as-of Review projection and authenticated composition with producer failure represented as unavailable rather than zero. #266 remains Draft; shared #249 root CI/Security/Commercial/CodeQL evidence defects are not being copied into the Planning leaf.

  10. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Planning producer work advanced in dependency order.

    #266 now owns the durable database invariant (todo ⇒ completed_at IS NULL; done ⇒ completed_at >= created_at) through staged NOT VALID → separate VALIDATE CONSTRAINT migrations. Its focused hosted PostgreSQL evidence is GREEN; remaining exact-head CI/Security/Commercial/CodeQL failures are inherited shared-control/package/evidence paths rather than Planning migration failures, so no leaf suppression or source copy is being added.

    The next causal Planning slice is now Draft #267, based directly on #266 rather than mutable main. Initial exact canary 34500566320 / job 102950006399 is a real RED: frozen install completed and the focused contract failed because ./task-completion did not exist. The contract requires a server-owned completion instant, atomic status + completed_at mutation, tenant-scoped non-disclosing lookup semantics, pre-persistence identifier validation, and fail-closed returned evidence. This avoids treating browser-authored completion timestamps or Review-owned counts as Planning truth.

    #267 remains intentionally below the HTTP/BFF and Weekly Review projection layers. After its application/persistence transition is exact GREEN and the temporary canary is retired, the next Planning slice is the authenticated HTTP mutation, then a bounded producer-owned Review projection with period/as-of/provenance semantics. overdue, stalled, and inactive remain forbidden until their separate producer-owned temporal concepts and estimands exist.

  11. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Planning producer prerequisite progressed through #267. Review found that mocked SQL evidence was insufficient, so the slice now executes the completion transition against real PostgreSQL with Planning migrations 0001–0006. That real execution exposed a clock-domain chronology defect: task created_at is database-owned while the completion instant is application-server-owned, so clock skew could make completed_at < created_at and trip tasks_completion_state_check. Hosted RED 34506258957 / 102969077398 reproduced PostgreSQL 23514. The minimal repair bounds a new completion by durable created_at with GREATEST($4::timestamptz, created_at) while preserving an existing first completion on retry. Hosted GREEN 34506520166 / 102969970441 passed formatting, Planning typecheck, real PostgreSQL integration 8/8, and Planning build; the temporary verifier was removed in 4667d73f48fad4e2088b770c06859f4f56629f98.

    This advances authoritative completion chronology only. #263 remains open: Planning still lacks the producer-owned temporal concepts/estimands needed for overdue/stalled/inactive, and authenticated Review composition plus partial-failure/unavailable semantics, locale/a11y/E2E, and buyer-path performance evidence remain separate work.

  12. seonghobae commented on Sep 10, 2026

    @seonghobae
    ContributorAuthor

    Planning producer hardening advanced in #267. The completion transition now has hostile dependency/evidence coverage in addition to chronology/retry/PostgreSQL integrity coverage: raw repository/SQL rejections and revoked producer/result/row accessors are collapsed to a stable credential-free persistence error rather than leaking backend/native error detail. Hosted RED 34512795939 / 102990810962 proved 5/5 hostile cases were previously escaping; PostgreSQL-backed verifier 34513428930 / 102992894109 then passed the full Planning suite (23 files, 167 tests), typecheck, formatting, and build. The temporary verification workflows were removed; #267 current workflow-free descendant is 81602d6e5167e1afdd9be7dfaaa0daff6ff841fd.

    This does not complete #263. Planning still needs producer-owned temporal truth/estimands for overdue, stalled, and inactive (due/status-transition/activity chronology rather than inference from current status), then an authenticated Review/BFF composition that distinguishes unavailable producer evidence from zero, plus current-head locale/a11y/E2E and real buyer-path p95 evidence. Keep those as dependent slices rather than moving Habit truth or browser-authored aggregate counts into Planning.

  13. 7 remaining items

  14. seonghobae commented on Sep 11, 2026

    @seonghobae
    ContributorAuthor

    Planning completion-history foundation advanced on #269. Current exact #269 head 3f7869e9499f699545b5147868df2b9bb726701c now enforces two database-level historical-evidence invariants: completion facts cannot predate owning-task creation, and accepted facts reject ordinary UPDATE while authorized data-rights/cascade DELETE remains possible. The latest hosted verifier first reproduced UPDATE acceptance as a real PostgreSQL RED, then passed the repaired chronology/history/data-rights slice 8/8 and the complete Planning suite 27 files / 201 tests, plus typecheck/build/format checks; temporary writer workflows were removed before publication.

    This does not close #263. Completion facts still do not provide the producer-owned due-date, status-transition, and activity chronology needed to define historical overdue, stalled, and inactive without inference. The next causal Planning lane remains those temporal authorities plus explicit estimands; only then should authenticated Review composition consume released/accepted producer evidence with unavailable kept distinct from zero.

  15. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Fresh Habit-owner evidence for the remaining Review gap: current #264@faab5d1dac875c7a325cf97fd03715a249dd9069 now bounds hostile PostgreSQL projection evidence and enforces the 100-Habit ceiling, but it still cannot satisfy this issue's historical rule-change acceptance.

    Current Habit migrations on that exact head are 0001_recurring_habit_core.sql through 0003_data_rights_authority_replay.sql. The domain persistence in 0001 stores one current habit.habit_definitions row (title, timezone, recurrence, starts_on, created_at) plus append-only completion events; there is no effective-dated/versioned Habit-definition history. HabitService.projectReviewWeek() reads those current Habit rows and calls generateHabitOccurrences() for the requested historical week, then fingerprints the resulting normalized projection. Consequently projectionRevision proves deterministic projection content, but it is not durable historical definition authority and cannot prove that a later recurrence/timezone/title change leaves an earlier Review denominator unchanged.

    Keep the existing acceptance requirement "Rule changes must not rewrite historical opportunities" open. The next Habit-owned slice should introduce a canonical effective-dated/versioned definition-revision contract (or an equivalent producer-owned temporal aggregate), select the revision effective for each scheduled local date/timezone when projecting a historical week, preserve data-rights erasure semantics, keep bounded/no-N+1 persistence access, and expose exact producer revision/as-of provenance. Do not solve this by Review/Web persistence, cross-service SQL, browser snapshots, or source-copying another bounded context.

    This is a buyer-gap handoff, not a claim that #264 is currently GREEN: its exact purpose verifier 35064770435 remains queued.

  16. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Habit historical-definition authority is now an executable stacked RED lane rather than only a handoff. Draft #281 is based directly on current #264 faab5d1dac875c7a325cf97fd03715a249dd9069; exact #281 head is 7334fe218bf82f7192a8f5e2dc0bcfcf5fd8a327.

    The permanent PostgreSQL regression applies every Habit migration in order, persists a daily definition for the 2026-09-07..13 Review week, mutates the current durable definition to weekly afterwards, then requests the historical week at asOf=2026-09-13T23:59:59Z. Acceptance requires the original daily title/recurrence and seven opportunities. This exercises the real Postgres repository rather than a synthetic row fixture.

    Purpose run 35072345404 uses pinned PostgreSQL 16 Alpine and validates formatting/typecheck before the behavioral integration test. It is currently queued, so no reality RED is claimed yet and no speculative temporal migration has been added. If the exact run fails at the expected historical-rule assertion, repair remains Habit-owned/effective-dated with data-rights and bounded-read semantics preserved. #264's own pending verifier lane is untouched.

  17. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    #281 review found a contract gap before temporal persistence work can be considered a buyer-realistic RED. HabitController/HabitService currently have no Habit-definition change command; #281 therefore overwrites habit.habit_definitions with direct SQL. That is useful evidence that the current single-row schema cannot reconstruct overwritten state, but it does not yet exercise Habit-owned mutation authority and it carries no effective-at/revision value. As written, it also cannot distinguish a post-period rule edit from an edit inside the review period.

    Foundation-first order for this slice: define the Habit-owned rule-change Ubiquitous Language/invariant and explicit effective boundary/revision; expose the minimal domain/repository mutation contract; then keep two permanent PostgreSQL regressions: (a) a post-period change cannot rewrite the completed week's denominator, and (b) an in-period change affects scheduled opportunities only from its effective boundary. Review/Web remain read-only consumers; no cross-service SQL or Review-owned snapshots. #281 stays Draft and should not proceed to the temporal production fix until its exact hosted run is terminal and this mutation-authority gap is repaired or explicitly split into a prerequisite PR.

  18. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    2026-09-16 current Habit temporal-authority follow-up: #282 (test(habit): require effective-dated rule change authority) is now the dependency-ordered successor to #281. Exact #282 head is b7e8a0f9edffa5c8babd81de03ae5089e327e75c, direct base #281 7334fe218bf82f7192a8f5e2dc0bcfcf5fd8a327.

    #281 remains a lower-level persistence-history probe because it expresses change by direct SQL. #282 instead fixes the acceptance boundary first: the regression requires a Habit-owned reviseHabitDefinition(...) application command with explicit effectiveFromLocalDate and versioned revision evidence, then carries two real-PostgreSQL semantics in the same test: (1) a post-period revision cannot rewrite an already completed week's title/7-opportunity denominator; (2) an in-period Thursday revision changes scheduled opportunities only from that effective boundary (Mon-Wed old daily rule + Friday new weekly rule = 4).

    No production temporal schema or repository repair has been added yet. Exact purpose run 35083422432 is currently queued/non-terminal, so this is test-first input rather than reality RED evidence. Only after terminal failure localizes to the absent/incorrect Habit-owned rule-change authority should the next descendant introduce the minimum Habit-owned revision aggregate/repository/migration repair. Review/Web snapshots, cross-service SQL, and direct-SQL execution time remain invalid substitutes for domain effective time.

  19. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    2026-09-16 Planning follow-up while #267 evidence is still queued: new stacked Draft #283 (test(planning): require durable task due authority) is exact 39540f0184b360ad476a453c6c2da9d9dac5ecab, direct base #269 6aade6e684ad27d8b6c8a611ba30eb6be7395b89, and ordinary ancestry is confirmed ahead-only 2 / behind 0.

    This does not define overdue yet. It isolates the producer prerequisite first: Planning must own optional Task.dueAt as canonical UTC deadline evidence, persist it through restart, expose undated tasks as explicit dueAt: null, and reject non-UTC API input instead of letting Review infer a deadline from createdAt or browser state. dueAt is expressly not scheduled/time-block authority.

    Purpose run 35084871820 is queued/non-terminal, so #283 is test-first input rather than reality RED or delivered due support. Only after an exact terminal failure localizes to missing/incorrect Planning due authority should the descendant add the minimum Task/repository/migration/API repair; overdue := todo + dueAt < asOf (with a separately specified boundary) remains downstream of that durable primitive. Existing completion-history facts on #269 remain independent and are not reinterpreted as deadline evidence.

  20. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Habit temporal-authority currentness: stacked Draft #282 is now exact 5052b05e19720a7a55e091fef3691b7e73b53f1c on #281 7334fe218bf82f7192a8f5e2dc0bcfcf5fd8a327. Fresh review found the predecessor no-backdating case could be satisfied by comparing effectiveFromLocalDate against the UTC calendar date. The permanent PostgreSQL regression now records at 2026-09-13T16:00:00Z (2026-09-14 in the seeded Asia/Seoul Habit) and attempts effective local date 2026-09-13, so the eventual rule-change authority must derive the boundary from Habit-local calendar semantics. No production/migration repair has been applied. Exact verifier 35091398604 is queued/non-terminal; do not call this reality RED or implement temporal persistence until it executes and localizes the failure to the missing/incorrect Habit-owned rule-change contract.

  21. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Habit temporal-authority follow-up, exact source #282@2d5121093a3c25047a7e72564da24bf5f783a52c.

    The existing #263 rule-change requirement needs one more invariant before a temporal schema can be implemented safely: when a revision can change timezone and effectiveFromLocalDate in the same command, the incoming timezone must not choose the clock used to authorize its own effective boundary. Backdating is therefore validated against the currently persisted Habit timezone. Only after that boundary is accepted may the proposed timezone become part of the new revision.

    #282 now carries a real-PostgreSQL discriminating regression: persisted Pacific/Kiritimati (UTC+14), server recording instant 2026-09-13T12:30:00Z (Habit-local 2026-09-14), proposed Pacific/Honolulu (local 2026-09-13), attempted effectiveFromLocalDate=2026-09-13. The mutation must fail and historical Review evidence must remain on the prior daily definition. A validator using the proposed timezone would incorrectly accept this command.

    This is still test-first authority only. Exact verifier run 35094264570 targets 2d512109... and is queued/non-terminal, so no reality RED, temporal migration, GREEN, merge, or release claim is made yet. Parent #281/#264 evidence gates remain independent; no cross-service SQL or Review-owned snapshot is introduced.

  22. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Habit temporal-authority currentness — #282 now exact b893c959d3b8a3e52cf4925bfb6d4818256db87d. Review of predecessor 2d512109... found the focused regression file lacked an EOF newline while its exact workflow executes prettier --check before Vitest, so that generation could have produced a harness RED before the intended missing reviseHabitDefinition(...) domain RED. b893c959... is an ordinary style-only descendant that terminates the file; the effective-dated rule-change semantics, persisted-timezone authorization invariant, PostgreSQL fixture, and production Habit source are unchanged. Exact replacement run 35099850801 is queued/non-terminal. Keep #263's historical-opportunity gap open and do not treat #282 as reality RED/GREEN until that current-head verifier reaches the intended behavioral assertion.

  23. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Planning overdue prerequisite currentness: #283 is now exact ab3614b30ac08d5566ae0bb9c44075a514f5e632 on #269 6aade6e684ad27d8b6c8a611ba30eb6be7395b89. The test-first deadline contract now closes an ambiguity the previous head left open: omission and explicit dueAt: null must both mean the same Planning-owned no-deadline authority and both must read back durably as dueAt: null; downstream Review must not interpret field absence. No overdue estimand or production dueAt implementation is claimed. Exact verifier 35106262458 is queued/non-terminal, so this remains acceptance specification rather than RED/GREEN evidence.

  24. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Planning deadline-authority successor #283 has advanced by ordinary test-only descendant to exact 534e23209b726ab7beafcacd165d9cb69f4ba5a5 on #269 6aade6e684ad27d8b6c8a611ba30eb6be7395b89. Fresh review found the prior positive fixture used only ...000Z, so an implementation could truncate all deadlines to whole seconds or reject non-zero milliseconds and still satisfy the contract. Current regression now persists/restarts exact 2026-09-18T09:00:00.123Z and rejects equivalent noncanonical +09:00, +00:00, missing-millisecond, and excess-fraction aliases. This keeps dueAt as Planning-owned canonical UTC deadline authority and does not infer overdue from createdAt or move deadline truth into Review/Web. Exact verifier 35116341416 / job 104862601512 is queued with no runner/steps, so this is not yet reality RED and no production dueAt repair is claimed.

  25. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Current Habit temporal-authority successor #282 has advanced by ordinary descendants to exact f24377589cb3fcd9bf7753911fb765f48a36f1c0 on #281 7334fe218bf82f7192a8f5e2dc0bcfcf5fd8a327. Fresh review found that the prior idempotency regression used the same HabitService instance for first acceptance and retry, so a process-local retry map could satisfy the contract. The current test-only lineage adds a real-PostgreSQL durable-idempotency case: accept the rule change on Sep 14, reconstruct both repository and service over the same database, advance the service clock to Sep 15, and require an exact retry to return the original revision evidence/recordedAt; reuse of the same key with a different, currently valid Sep 15 command must reject. This keeps Habit as the sole owner of temporal definition/idempotency truth and requires exact retry recognition before ordinary backdating validation. The final descendants are formatting/harness normalization only; no production Habit schema/repository/service repair has been made. Exact verifier 35126833960 is queued; do not promote this to reality RED/GREEN until it executes past formatting/typecheck/bootstrap.

  26. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Habit temporal-authority currentness (2026-09-17): #282 advanced test-only to exact 6be2d832fd9847cce35fb20d9cb3a344a4529c01. Review found restart durability alone did not prove multi-replica atomicity. New real-PostgreSQL regressions race two independent HabitService/PostgresHabitRepository instances: the same idempotency key must converge on one identical revision/evidence, and different keys/payloads racing the same (habit, effectiveFromLocalDate) boundary must yield exactly one acceptance. A following boundary must be revision 3, detecting duplicate allocation. Exact hosted verifier is run 35132516248, currently queued/non-terminal, so this is not yet reality RED and production temporal schema/command repair remains gated.

  27. seonghobae commented on Sep 16, 2026

    @seonghobae
    ContributorAuthor

    Planning producer-authority update — 2026-09-17

    Completion-history work is not yet safe to consume as Weekly Review truth. #269 current regression-only exact d047fd16a33d83f8edf40cecb4df46b2233fa198 now covers both missing source-authenticity cases: a valid-looking direct fact while the durable task is still todo, and extra direct matching/later completion facts after a legitimate repository todo → done. Both must fail under task_completion_facts_source_transition_check while legitimate history remains intact. Fresh verifier 35144761658 is queued/non-terminal, so this is not yet a reality RED or a repaired contract.

    Until #269 proves and repairs that invariant, Review must not compose completion counts from task_completion_facts merely because rows are immutable and chronology-valid. A projection derived from forgeable producer history would turn a persistence integrity gap into buyer-visible false evidence. #283's due/deadline authority also remains downstream of #269 and must reacquire evidence after normal parent adoption.

    Keep the existing rule here: unavailable ≠ 0, no Review-side filtering as a substitute for producer invariants, and no cross-service SQL.

  28. seonghobae commented on Sep 17, 2026

    @seonghobae
    ContributorAuthor

    Habit historical-denominator prerequisite currentness: #281 remains exact de4c4a3e266020354dec62586210f89479a8cba8 on #264 24ad8bf87404452f66baf66d3d3a99e2632b419e; verifier 35161273244 is still queued with no runner. #282 advanced by an ordinary test-only descendant to 4b4e7ea16095e30b0c89f84bd1d544166f69b00f, verifier 35165398086. The added acceptance closes a semantic-idempotency hole: equivalent Habit rule representations after existing domain normalization (trimmed title/timezone; deduped/sorted weekly weekdays) must replay the original revision evidence under the same key, while real semantic changes still conflict. No producer implementation or Review projection may claim this prerequisite GREEN yet, and #282 still must adopt the settled current #281 lineage before it can become consumable authority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions