Commit Graph
261 Commits
Author SHA1 Message Date
Jesse_ChenandCursor e87c58d6e4 fix(report): persist longform appendix on self-hosted upsert (BUG-576)
Engine calls already returned markdown; the worker failed because local postgres upsert required onConflict and the appendix write omitted it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 14:19:21 +08:00
Jesse_ChenandCursor 1ded6bb0d4 fix(rectification): hide option hover impact and composer step strip (BUG-575)
Hovering A/B/C/D rewrote a leading/lagging time line and made the card flicker; the step-state sentence above the composer was instructional filler, not something the user needed to answer.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 14:07:49 +08:00
Jesse_ChenandCursor 8e31680b45 fix(rectification): honor declared birth-time uncertainty and split windows over two hours (BUG-571–573)
Intake stores how sure the user is; rectification now searches that range, offers a one-click widen when event fit is low at the edge, and trisects windows longer than two hours before the minute grid.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 12:18:50 +08:00
Jesse_ChenandCursor 814c924e4a fix(rectification): exhaustion exit, explain layer, range reading, unknown-time scan (BUG-565–568)
Independent Staging Quality Gate / validate (push) Successful in 9m20s
Independent Staging Quality Gate / publish (push) Successful in 6m51s
Keep askable cards after exhaustion, explain each probe, read the adopted credible range in reports and chat, and compare declared periods before the minute grid when the clock is unknown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 09:10:37 +08:00
Jesse_ChenandCursor 150d7ef189 fix(web): exit rectification when the probe pool is exhausted (BUG-558)
Stop falling through to "say another event" after dated and occupation collect are done. Deliver an adopt path or a gate sentence, and add a spoken-collect stop control.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 23:03:11 +08:00
Jesse_ChenandCursor ebc8380fb8 fix(report): defer lazy-section setState so staging lint can pass
IntersectionObserver fallback called setVisible inside useEffect, which the
react-hooks compiler treats as an error. Queue it on rAF so the gate can
publish the MD report page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 22:33:38 +08:00
Jesse_ChenandCursor cfcd369d4f feat(report): render longform Markdown as the report and close gaps2 holes
New reports skip the writer, persist pl9 Markdown as the body, and settle zero-token usage on the catalog model. Planned longform sections now emit blocked rows instead of vanishing.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 21:46:16 +08:00
Jesse_ChenandCursor dc6598d7e4 fix(web): keep the settings dialog one size and move billing into it (BUG-554)
The four account panes now share a fixed frame, chart profiles open as list then detail, and membership lives in the homepage dialog instead of a separate page.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 18:29:51 +08:00
Jesse_ChenandCursor bf8ad0d1ff fix(web): keep consultation conclusions across turns and surface cache hits (BUG-555, BUG-556)
Session history was silently clipped to the first 4000 characters of the last 12 messages, so follow-ups could not see timing or audit tables. Keep an append-only tail plus a checkpoint summary, retry overflow in the same request, and expose cache hit rate in admin usage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 15:16:18 +08:00
Jesse_ChenandCursor a1956deb63 fix(web): summarize session titles, sort by activity, and paginate history (BUG-553)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 14:34:30 +08:00
Jesse_ChenandCursor 055b7adca9 fix(web): keep composer enabled while generating and treat stop as neutral (BUG-551, BUG-552)
Enter now queues one follow-up instead of dropping it, and a rectification stop leaves the streamed reply with a grey notice instead of an error alert.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-06 13:08:43 +08:00
Jesse_ChenandCursor bab0718700 feat(report): ship full-mode longform appendix beside the five-chapter report
Independent Staging Quality Gate / validate (push) Failing after 9m41s
Independent Staging Quality Gate / publish (push) Has been skipped
Web export now calls the same full pack as the long skill report and caches an owner-only Markdown download. Appendix failure stays unavailable and does not change the main report status.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-05 11:10:44 +08:00
Jesse_ChenandCursor 329f8a2109 fix(rectification): pin the adopt card and drop casual adopt copy
Independent Staging Quality Gate / validate (push) Successful in 11m34s
Independent Staging Quality Gate / publish (push) Successful in 1m56s
The time card stayed under an earlier collect question, and the close said to just use a time for now. Keep the card on the delivery turn and present the analysis as this round's result.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-05 02:03:19 +08:00
Jesse_ChenandCursor d4627a5019 fix(rectification): dedupe post-adopt verify and skip this probe only
Independent Staging Quality Gate / validate (push) Successful in 14m31s
Independent Staging Quality Gate / publish (push) Successful in 1m59s
Adopted reverse-verify repeated already-asked collect stems, treated 「这题跳过」 as stopping the case, and promised holdout/OOS checks that never ran. Collect spoken stems no longer prefix a year.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 21:51:59 +08:00
Jesse_ChenandCursor 7b1354a79b fix(ui): restyle personal report pages to the product reading room
Independent Staging Quality Gate / validate (push) Successful in 8m31s
Independent Staging Quality Gate / publish (push) Successful in 1m58s
The report centre and reader were a second newspaper identity. They now reuse canvas, hairline, and serif display tokens so the document feels like the rest of Jyotisha.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 16:30:44 +08:00
Jesse_ChenandCursor 41f973f036 fix(rectification): bind collect-denial follow-up to the asked turn
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Saying no to a spoken collect left the next stem only on current_question, so the preparing spinner never cleared. Persist the ack, link asked_turn_id, and emit run.completed with turnId (BUG-525).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 16:27:53 +08:00
Jesse_ChenandCursor cfa824994e fix(rectification): keep a live analyzing step and drop the range-stop exits
Independent Staging Quality Gate / validate (push) Successful in 9m26s
Independent Staging Quality Gate / publish (push) Successful in 1m57s
A completed tool left only checkmarks under 正在分析, so the run looked stuck. The composer and scoring-card 先这样 buttons were unused early exits.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-04 12:46:10 +08:00
Jesse_Chen a7041529c1 feat(reports): add birth time sensitivity 2026-09-04 02:11:57 +08:00
Jesse_Chen 3b09bbbee0 feat(reports): add professional reference export 2026-09-04 00:19:28 +08:00
Jesse_Chen c2f23131f7 feat: add health consultation report pipeline 2026-09-03 23:57:27 +08:00
Jesse_Chen 027e4b0827 fix(frontend): remove undefined ayanamsa class
Independent Staging Quality Gate / validate (push) Successful in 16m5s
Independent Staging Quality Gate / publish (push) Successful in 2m7s
2026-09-03 22:34:51 +08:00
Jesse_ChenandCursor b6a70aa7df fix(ayanamsa): pin Lahiri on reference sets and add a user setting
Product default stays Raman. Public-case revalidation and fixture dashas now pass --ayanamsa lahiri; profiles store the four selectable values.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 16:33:46 +08:00
Jesse_ChenandClaude Fable 5.1 3c33e59814 feat(rectification): confirm the tap on the choice card and show the declared minute on the empty board
The choice card now marks the tapped option with a check and 已选择 and,
while the tap is being recorded, carries the same live row shape as a
timeline step instead of only a wait cursor. Before any candidate exists
the board's clock shows the declared birth minute, its body says what
fills it later, and the column narrows to minmax(16rem, 18rem); the
compact peek reads "填报 HH:MM". No house table is invented for the
declared time — the Case API does not provide one.

BUG-508, BUG-509

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-03 07:07:31 +00:00
Jesse_ChenandClaude Fable 5.1 1e50007c50 fix(rectification): keep one live row from a tapped choice or an adopted candidate through the follow-up turn
After a choice was recorded the chat removed its "正在记录本次选择…" row,
dropped `busy`, and let an effect start the follow-up turn a frame later —
one blank frame, and the next card could flash before the turn hid it.
Adopting a candidate showed nothing but a greyed button. `send` now takes a
continuation that reuses an existing live row, the choice and adoption
flows await it in the same async chain, `busy` is held throughout, and
adoption puts "正在采用 HH:MM…" at the end of the transcript before the
round trip.

BUG-506

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-03 07:07:31 +00:00
Jesse_ChenandClaude Fable 5.1 360989ca2c fix(rectification): make every gap a live row with retries, give an empty Case a start, and say why a run stopped
The chat used to show "当前没有可回答的问题,正在等待服务端更新" / "当前问题暂时无法显示"
/ "题目加载失败,请刷新" as bare copy above the composer. The gap between a
settled turn and its next question is now a state: `preparing` renders the
same timeline live row the reply uses ("正在准备下一个问题…") and refetches the
Case on a 2s timer up to two retries; `unavailable` renders one line and a
44px reload button. A snapshot that never arrived at hydration is the same
gap. A resumed Case with no turns and no server-started opening shows
"这段校正还没有开始。" with one 开始提问 action. Stopping a run keeps what
streamed and says so instead of "暂时不可用"; the opening turn's live row
names what is happening; a 402 explains itself for 600ms before leaving.

BUG-505, BUG-507

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-03 07:07:31 +00:00
Jesse_ChenandClaude Fable 5.1 53017d4153 fix(rectification): reveal the surface once — hydrate the Case before the switch, never remount, static entry feedback
Opening a rectification Case used to switch sessions first and read the
turns afterwards, so the reader saw a plain transcript, then an empty
panel, then a remount when the turns arrived (and again after the first
turn settled, because the panel key carried a ready/loading suffix).
The surface hook now reads turns and snapshot in one Case request under
the home reveal budget and only then makes the session active; the
sidebar defers the switch the same way; a session selected at bootstrap
(deep link, refresh) is hydrated during the prepare phase so the reveal
shows the surface itself; the panel key is the session/Case binding only,
later turns fill an empty transcript as a prop update, and unmounting
aborts any stream or snapshot read. The homepage card and the sidebar row
say 正在打开 statically while the Case opens — no spinner after the reveal.

BUG-505

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-03 07:07:31 +00:00
Jesse_ChenandCursor e8c98c37cf fix(rectification): restore collect-phase exit and drop the consult handoff
Independent Staging Quality Gate / validate (push) Successful in 8m29s
Independent Staging Quality Gate / publish (push) Successful in 1m45s
Public can_adopt no longer starves the collect fallback, 改选 scrolls to
the offer, opening collect uses other, and probe_year stays on the
schema. The status bar no longer starts an empty consultation chat.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 10:41:36 +08:00
Jesse_ChenandCursor 35e5781e66 fix(rectification): gate collect-phase adopt cards and keep post-adopt verify answerable
Independent Staging Quality Gate / validate (push) Successful in 9m50s
Independent Staging Quality Gate / publish (push) Successful in 1m53s
Public can_adopt follows session_outcome; reverse_verify reuses the persisted question id; offer cards settle on the owning message with a status-bar handoff.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 09:29:34 +08:00
Jesse_ChenandCursor eda37c1523 fix(report): classify writer failures and size CJK section budgets
Independent Staging Quality Gate / validate (push) Successful in 9m41s
Independent Staging Quality Gate / publish (push) Successful in 1m49s
Staging personal_full died as report_schema_invalid after the first
chapter blocked. Keep assertWriterOutput, stop treating refs mismatch as
missing evidence, and surface section error codes on the report APIs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-03 01:17:46 +08:00
Jesse_ChenandCursor 3568801509 fix(rectification): keep the choice selected state inside the button
Independent Staging Quality Gate / validate (push) Successful in 10m25s
Independent Staging Quality Gate / publish (push) Successful in 1m57s
The outer focus ring overflowed the message bubble and stacked on the existing selected border. Draw keyboard focus inset and skip auto-focusing the first option.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 21:44:55 +08:00
Jesse_ChenandCursor 8dfe457f21 fix(rectification): keep choice options and scoring on the server
Independent Staging Quality Gate / validate (push) Successful in 9m30s
Independent Staging Quality Gate / publish (push) Successful in 1m50s
Agent set-focus was writing or dropping choice schema, so probes never scored. Force server-owned options, fail closed when focus list RPC errors, and require the probe year in spokenPrompt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 20:47:16 +08:00
Jesse_ChenandCursor d94049769e fix(rectification): put each question inside the assistant message
Independent Staging Quality Gate / validate (push) Successful in 25m7s
Independent Staging Quality Gate / publish (push) Successful in 2m8s
Focuses now carry asked_turn_id so GET rebuilds stem and options on the
same turn. Agent writes spokenPrompt; the live question slot is gone.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 19:55:20 +08:00
Jesse_ChenandCursor 33d55b3a54 fix(rectification): satisfy React compiler lint for collect stem attach
Independent Staging Quality Gate / validate (push) Successful in 9m21s
Independent Staging Quality Gate / publish (push) Successful in 1m49s
Move the current-question ref off render and persist the collect stem from snapshot/send callbacks so ESLint no longer fails the staging gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 17:05:29 +08:00
Jesse_ChenandCursor b1d4796d30 fix(rectification): restore showActivity source lock for the staging gate
Independent Staging Quality Gate / validate (push) Failing after 8m5s
Independent Staging Quality Gate / publish (push) Has been skipped
Keep collect text on bubbleMessage but pass displayedMessage.state so the entry contract matches again.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 16:49:31 +08:00
Jesse_ChenandCursor 42c6de142b fix(rectification): put the collect stem in the assistant bubble
Independent Staging Quality Gate / validate (push) Failing after 8m27s
Independent Staging Quality Gate / publish (push) Has been skipped
The live question slot still rendered the collect prompt below the action icons when the streamed body was only a greeting. Join the GET prompt into that bubble and stop drawing a sibling collect slot.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 16:30:26 +08:00
Jesse_ChenandCursor 39c30b5597 fix(rectification): persist the collect stem on the same assistant turn
Independent Staging Quality Gate / validate (push) Successful in 7m55s
Independent Staging Quality Gate / publish (push) Successful in 1m47s
The live question slot disappeared on refresh because it was never written to assistant_message. Attach the current collect_spoken prompt to that turn before finalize so chat history keeps it.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 16:06:50 +08:00
Jesse_ChenandCursor 661a0dab14 fix(rectification): stop the opening body from repeating the collect prompt
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
Persist the interview slot before the opening turn, keep the stem in the question slot, and hide that slot while a run is busy so the same ask does not appear twice.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 14:53:10 +08:00
Jesse_ChenandCursor aab3ad4b84 fix(rectification): keep choice stems visible and align overlay adopt with the engine
Independent Staging Quality Gate / validate (push) Successful in 7m44s
Independent Staging Quality Gate / publish (push) Successful in 1m48s
Walkthrough polish: fail-closed empty D9 prompts, stop asserting the next question is on screen, vary same-domain collect copy, switch to reverse-verify after adopt, and let coverage route interview without blocking can_adopt.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 13:11:22 +08:00
Jesse_ChenandClaude Fable 5.1 482796fc52 fix(chat): reveal the home page once after a two-phase bootstrap
The loading screen now owns every wait: starter questions, today's
starlanguage and the rectification entry summary are fetched in a prepare
phase before reveal (4s budget, static fallbacks), the rectification chunk is
warmed, recent sessions are prefetched, and no component spinner remains
after the page appears. BUG-479.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0193vBv6w5MV2cifdTUu9H5P
2026-09-02 04:39:04 +00:00
Jesse_ChenandClaude Fable 5.1 f542c02490 refactor(chat): share composer, scroll follow and jump control across both chat surfaces
The rectification session rendered its own textarea (no length ceiling,
no count), its own rAF scroll follow with a sticky-scroll helper, and its
own jump chip styled differently from the main chat's inline Tailwind
button, while the main chat re-ran scrollTo on every streamed token and
added a smooth scroll on settle. ChatComposer now accepts a controlled
value so the rectification surface reuses it without touching the main
draft store; useConversationScrollAnchor owns the follow through a
ResizeObserver, one frame per content change, for both surfaces; a
single JumpToLatestButton replaces both chips; the 720px transcript
override is gone. DESIGN.md records the shared composer, the jump
control, the reading width and the two shadow tokens.

BUG-477 BUG-478

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-02 04:29:01 +00:00
Jesse_ChenandClaude Fable 5.1 6356d7b549 refactor(chat): render rectification activity through the shared step timeline
The rectification surface had its own activity pipeline: a trace panel
with a 20px canvas orb clipped inside a 14px marker, a list that never
collapsed, a second receipt disclosure under every reply, an inline
failure banner and a staged label while regenerating. Its trace and
receipt are now projected onto ConsultationTimelineRow so both surfaces
render one ConsultationRunTimeline with one live marker and one settled
summary; receipt methods become source chips on the last completed row.
The unreachable sections-report/step-tree path, the trace panel, the
receipt component and the thinking-orbs dependency are removed. The
server-side drop of rectification thinking deltas is untouched.

BUG-476

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-02 04:29:01 +00:00
Jesse_ChenandClaude Fable 5.1 aff9d19343 fix(chat): keep the latest reply mounted through settlement and animate the timeline collapse
The streaming and settled versions of the trailing assistant reply were
two components, so settling unmounted one and mounted the other and the
entrance tween replayed over text the reader was already on. One
LatestAssistantEntry now owns that row under a single key, and the
history list excludes it. The CSS entrance keyframe that doubled the
GSAP tween is gone and the tween matches the documented 160ms. The step
timeline no longer remounts on settle: it is a button-controlled
disclosure with a 180ms grid-rows transition, the reader's own toggle
wins over the live default, and an in-flight request with no events yet
shows a queued row instead of an empty shell.

BUG-474 BUG-475

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-02 04:29:01 +00:00
Jesse_ChenandClaude Fable 5.1 ad9dba5c79 perf(chat): coalesce stream events per frame and pace text release
Every NDJSON event used to commit its own React update and re-parse the
whole partial answer through react-markdown, so long replies grew
quadratically slower. Stream events now land in a frame buffer that
flushes at most once per animation frame, releases answer and thinking
text at a steady pace with a twelve-frame catch-up, and settles
synchronously on completion, failure and abort. Streaming markdown is
split at the last completed block so only the tail is re-parsed each
frame. Applied to both the consultation hook and the rectification chat.

BUG-473

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
2026-09-02 04:29:01 +00:00
Jesse_ChenandCursor 1a3e14e726 fix(rectification): show question stems and unblock adopt after occupation
Independent Staging Quality Gate / validate (push) Successful in 13m40s
Independent Staging Quality Gate / publish (push) Successful in 9m59s
Choice legends and spoken collect prompts were hidden after BUG-461, and occupation still blocked canAdopt once dated coverage was done. Restore visible stems and stop polling extra collects when adopt is allowed.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 11:09:56 +08:00
Jesse_ChenandCursor 058e5db9b5 fix(chat): make Home pass react-hooks lint after the split
Independent Staging Quality Gate / validate (push) Successful in 17m39s
Independent Staging Quality Gate / publish (push) Successful in 7m11s
eslint-plugin-react-hooks now analyzes the smaller Home, so render-time ref writes and sync effect setState were failing the staging gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 07:01:36 +08:00
Jesse_ChenandCursor ed9497e76a fix(voice): speak first, then keep Level 2 skeleton and boundary semantics
Natal answers were opening on parameter tables, and rectification turns were one-sentence legal copy. Centralize user-facing strings, keep representative-minute and question-slot red lines, and stop duplicating the opening collect prompt as a second assistant message.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 02:27:50 +08:00
Jesse_ChenandCursor 54269fcfcc refactor(chat): extract home helpers, chart library, and starter surfaces
Independent Staging Quality Gate / validate (push) Has been cancelled
Independent Staging Quality Gate / publish (push) Has been cancelled
page.tsx still owns the chat main chain, but the first product surfaces now
live in their own modules so later splits can land without editing the 4k-line
Home. Source-lock tests follow the moved tokens; the orphan user-data contract
is aligned and added to the quick gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 22:58:02 +08:00
Jesse_ChenandCursor 75fc456d7e fix(rectification): drop duplicate collect cards and false run_failed
Independent Staging Quality Gate / validate (push) Successful in 10m23s
Independent Staging Quality Gate / publish (push) Failing after 8m59s
Spoken collect no longer renders a second visual prompt; choice legends stay screen-reader only and live cards share the assistant inset. Exhaustion collect avoids colliding with the opening question id, and a successful billed turn no longer surfaces run_failed after the exit gate.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-01 15:19:00 +08:00
Jesse_Chen 4b1331776d fix(rectification): fail closed UI and question ownership
Independent Staging Quality Gate / validate (push) Successful in 12m32s
Independent Staging Quality Gate / publish (push) Has been cancelled
2026-09-01 02:06:53 +08:00
Jesse_Chen afb8305ca1 fix admin feature pricing visibility
Independent Staging Quality Gate / validate (push) Failing after 26m23s
Independent Staging Quality Gate / publish (push) Has been skipped
2026-08-31 19:57:08 +08:00