Skip to content

[GA close-out B2] Engine-behaviour GA probes: #698, #1141, #691, #701, #520, #779 #1153

Closed

Description

@hotlong

Split from #1150 (GA close-out sweep) — the non-UI engine-behaviour half of groups 3 and 4, plus two cards handed over from #1151. Measurement only; no product code changes, no commits, no push, no PR.

Repo is on @objectstack/* 17.0.0 GA (#1146 / PR #1147), commit d4ddee0. Every card below was last measured on an rc build. Use port 4002 (HOTCRM_PORT=4002) — sibling agents hold 4001 and 4003.

Cards

Confirmation probes (#1150 group 3) — close if green

GA-retests (#1150 group 4)

⚠️ Handed over from #1151 — these were about to fall through the sweep

#1151 was asked to direct-close these two on recorded evidence and correctly refused, because the recorded readings do not establish a fix. They appear in no other probe set, so they are yours. Read #1151's refusal comment on each card first — it names precisely what is missing.

What to do per card

  1. Read the full body and every comment — original probe, exact commands, later re-measurements, PM triage that narrowed the card, and ([17.0-rc][疑似平台] datetime 字段的时间窗过滤返回空集(客服仪表盘全空) #520 / 批量写(multi: true)路径上 ctx.previous 恒为空 —— 15 个读 previous 的 hook 在该路径全部空转,知识文章可被批量写成「已发布但从未复核」 #779) [GA close-out A] Bookkeeping: record the #1106 verdicts as already-applied, direct-close the 8 verified-fixed rc-era cards #1151's refusal comment.
  2. Re-run the card's own reproduction on 17.0.0 GA. Before trusting a green, ask what the probe would print if the defect were still present. A probe that structurally cannot fail proves nothing — this repo has a documented case (Nine object files import F, P from @objectstack/spec and never use them — three of them above the license header #1091) of exactly that sitting in the backlog for a week. If a card's original repro has that shape, say so and build one that can fail.
  3. Non-reproducer ⇒ close with the reading (version, probe, result). Drop pm:blocked in the same label write where present ([17.0-rc][疑似平台] crm_case 自动编号计数器落后于既有 case_number:REST 建单连续 409,每次失败还烧掉一个号(实测重试 25 次才成功) #698, 批量写(multi: true)路径上 ctx.previous 恒为空 —— 15 个读 previous 的 hook 在该路径全部空转,知识文章可被批量写成「已发布但从未复核」 #779). A label update replaces the whole set — pass the full desired list.
  4. Survivor ⇒ leave open, post the GA reading, then file or refresh an objectstack mirror and nominate it on [Epic] v17 bug focus — Seat A: platform bugs (objectstack) objectstack#8667.
  5. Partial ⇒ for [17.0-rc][疑似平台] crm_case 自动编号计数器落后于既有 case_number:REST 建单连续 409,每次失败还烧掉一个号(实测重试 25 次才成功) #698 and A misspelled top-level stack key is silently stripped, not rejected — the artifact just loses it #1141 especially, the expected outcome is "one half fixed, one half live". Report halves separately; close only if every half in scope is green.

⛔ Boundaries

  • You nominate; you do not label. ⛔ Do NOT apply target:v17, do not edit the #8667 first-batch list. Nominations are comments naming the card and the evidence. #8667: "the PM nominates … the maintainer approves by labeling"; [GA close-out sweep] Apply the #1106 verdicts, close the verified-fixed rc-era platform cards, GA-retest the 8 likely-live ones #1150: "Seat A decides nothing".
  • #8667 scopes hotcrm out. Nothing from this card enters that theme except the mirror nominations above.
  • No fixes and no workarounds. Root cause belongs in the mirror, not in a patch here.
  • ⚠️ Do not trust "verified fixed" claims in this repo's account-book. Three separate "nobody executed this" premises have already been falsified during this sweep. Measure.

Worktree

Dev agents are working hotcrm concurrently — the shared checkout gets its HEAD moved under you. git worktree add ../hotcrm-issue-1153 -b claude/issue-1153-ga-engine-probes && cd ../hotcrm-issue-1153 && pnpm install. The pnpm store is pre-warmed (~1m43s). Existing REST-probe patterns worth reading first: e2e/fixtures.ts, e2e/opportunity-lifecycle.spec.ts, and test/helpers/ (hook-harness.ts, flow-harness.ts, action-sandbox.ts).

Acceptance

Activity

  1. added theissue type on Aug 14, 2026
  2. added
    upstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream
    pm:queueReady for the PM dispatch loop
    on Aug 14, 2026
  3. changed the title [-][GA close-out B2] Engine-behaviour GA probes: #698, #1141, #691, #701[/-] [+][GA close-out B2] Engine-behaviour GA probes: #698, #1141, #691, #701, #520, #779[/+] on Aug 14, 2026
  4. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 14, 2026
  5. self-assigned this
    on Aug 14, 2026
  6. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor

    Claim: PM loop round 2
    Session: session_01XAK3brMLjd4ykF4QAhFnuo
    Branch: claude/issue-1153-ga-engine-probes
    Worktree: hotcrm-issue-1153
    Domain: repo:hotcrm (parent #1150, engine half of groups 3 + 4, plus #520 / #779 handed over from #1151)
    File surface: throwaway probe scaffolding only, deleted before reporting; no product source (stop on breach; explain in the report)
    Container & model: L, mode:subagent, model: opus
    Serial constraints cleared: port 4002 reserved for this claim (siblings hold 4001 on #1152 and 4003 on #1154). Card surface #698 #1141 #691 #701 #520 #779 is disjoint from #1152 and #1154; #1151 is closed and released #520 / #779 to this card explicitly. No same-file predecessor PRs — no product files are edited.

    Scope grew after the card was filed: #520 and #779 were added when #1151 refused to close them on recorded evidence and no other probe set covered them.


    Generated by Claude Code

  7. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor

    Result — all 6 cards measured on 17.0.0 GA · 2 closed, 4 survive

    card half GA verdict action
    #698 burn-on-failure fixed —
    silent duplicate numbering REPRODUCES open · mirror objectstack#8686 · nominated
    #1141 naming (key is named) fixed —
    rejection (key still accepted) REPRODUCES, and --strict cannot catch it either open · mirror objectstack#8687 · nominated
    #691 403 PERMISSION_DENIED fixed (now 422) —
    the inconsistency itself (422 vs 400, no fields[], [Security] prefix, guard ordering) REPRODUCES open · mirror objectstack#8688 · nominated
    #701 — REPRODUCES, both flows open · mirror objectstack#8689 · nominated
    #520 — not reproduced at the dashboard layer CLOSED
    #779 — not reproduced, all three write shapes CLOSED, pm:blocked dropped

    Both "one half fixed, one half live" predictions in this card's item 5 were correct. #698 and #1141 came back exactly that way, and #691 turned out to be a third instance of the same shape that the card did not predict.

    On the two handed over from #1151

    Probes that could not fail were replaced

    Three of the six original repros had that shape and were rebuilt:

    Two probes caught their own defects mid-run and are worth recording: the first #698 burn probe planted its collision against the __global__ sequence and reported INCONCLUSIVE rather than green; the first #779 run reported registered:0, skipped:1 from the hook binder and aborted rather than measuring an engine with no hook bound.

    Report

    {
      "issue": 1153,
      "status": "done",
      "branch": "claude/issue-1153-ga-engine-probes",
      "pr": null,
      "premise_still_valid": true,
      "summary": "All six cards re-measured live on @objectstack/* 17.0.0 GA (hotcrm d4ddee0, dev server on port 4002, fresh seeded DB). #520 and #779 did not reproduce and were closed with full readings; #779's label write dropped the stale pm:blocked. #698, #1141 and #691 each came back one-half-fixed / one-half-live, and #701 reproduces outright on both named flows; all four stay open with GA readings, fresh objectstack mirrors (#8686/#8687/#8688/#8689) and one nomination comment on objectstack#8667. No target:v17 applied and the #8667 first-batch list untouched. No product code changed, no commits, no PR; scaffolding deleted and git status clean.",
      "tests": "Measurement-only card — no build/test gates apply. Probes, all foreground: (698) fresh-DB REST creates minted CASE-00001..4 duplicating seeds, duplicate case_number values [[CASE-00001,2],...]; two sequence rows __global__=38 and org_mssymr19xzd645gv=6 under UNIQUE INDEX (COALESCE(organization_id,'__global__'), case_number); burn half not reproduced - planted band CASE-00012..20, ONE create returned 201 CASE-00021 counter 11->21, rejected create left counter 22->22. (1141) safeParse accepts+drops 4 unknown top-level keys with a valid-stack positive control passing; validate exit 0 baseline and 0 with bogus keys, --strict exit 1 in BOTH (baseline control), warning sets byte-identical 88 vs 88. (691) six REST branches one session: master omitted 422 MISSING_REQUIRED_FIELD no fields[]; master present+unresolvable 400 VALIDATION_FAILED fields[reference_not_found]; same object master supplied + scalar omitted 400 VALIDATION_FAILED fields[2]. (701) case v5_h-3H_CbMj6jag fired to status=escalated then 1 loop-breaker WARN naming that id, guard terms status!='escalated'->false and escalated_date==null->false; opportunity RnrCSh-5GvgPkzSM same shape; 3 more WARNs unprompted during demo_bootstrap. (520) dataset/query vs SQLite truth: none 51/51, $gte 37/37, $lte 1/1, window 37/37, bare-date 1/1; 7 dashboard widgets windowed, 0 blank, 0 disagreeing; 21/21 widget-preset combinations via {N_days_ago}/{today}. (779) real engine + driver-memory + shipped knowledge_article.hook bound via bindHooksToEngine (asserted registered:2 skipped:0 before measuring): per-row input.id and previous bound on multi:true, bulk edit refreshes last_reviewed_at, bulk null-write leaves 0 of 2 published rows empty, single-row positive control healthy; ceiling boundary 10000 -> OK with 10000/10000 stamped, 10001 -> ERR_BULK_PER_ROW_HOOK_LIMIT with 0 rows written. Cleanup: dev server killed by recorded PID only (sibling on 4003 verified still 200), all scaffolding deleted, git status clean, objectstack.config.ts hash unchanged at bd8cb34b2d9c2bbf342d44ed94c0a2ec8e626184, git diff origin/main empty.",
      "open_questions": [
        {
          "question": "#698 is a SURVIVOR but I dropped its stale pm:blocked. This card ties that drop to the non-reproducer branch ('Non-reproducer => close with the reading, dropping pm:blocked where present (#698, #779)'), and grants 'whatever the outcome' only to #779. Was extending it to #698 correct?",
          "options": [
            "Keep it dropped — objectstack#5495 is closed as completed via merged PR objectstack#6932, so the card was blocked on a blocker that no longer exists, which is the instruction's own stated rationale",
            "Re-apply pm:blocked — the letter of the instruction scoped the drop to a close, and #1151 set the precedent of deliberately leaving the label on an open card"
          ],
          "recommendation": "Keep it dropped. The blocker is verifiably merged and a survivor that still needs platform work is exactly the card that must be dispatchable. Flagged in the card comment too, so it is a one-edit reversal if the PM disagrees."
        },
        {
          "question": "#520 was closed without a browser opening the dashboard, because the console's own preset->macro mapping table made the last unverified link measurable from the API side. Is that substitution acceptable, or should a browser pass on #1154 confirm it before the close stands?",
          "options": [
            "Close stands — 21/21 widget-preset combinations match ground truth through the exact spelling the shipped console emits, and the console mapping was read out of the shipped bundle rather than assumed",
            "Reopen until #1154 (or a follow-up) renders the dashboard with a picker present"
          ],
          "recommendation": "Close stands. What remains untested is the console's rendering, not the platform defect this card is about — and #1157 already carries a browser-verify step as part of restoring the picker, so the visual confirmation happens there with something to actually look at."
        }
      ],
      "out_of_scope_findings": [
        "filed as #1157: restore the Service dashboard's dateRange and relax the #546 CI guard — both upstream preconditions (objectstack#3912, #3777) have landed and the window is measurably correct on GA; unassigned, includes the daily_case_volume re-check and a browser-verify step",
        "filed as objectstack-ai/objectstack#8690: an unparseable date comparand on a datetime filter is passed through and compares false — HTTP 200, zero rows, no diagnostic — while an unknown {placeholder} on the same request is rejected 400 FILTER_TOKEN_UNKNOWN; same blank-screen symptom as #520 by a different cause, filed rather than folded in so #520's close stays honest"
      ]
    }

    Boundaries observed

    No target:v17 applied to anything; the #8667 first-batch list was not edited; nominations are comments. No product code changed — objectstack.config.ts verified byte-identical (bd8cb34b…), git diff origin/main empty, git status clean, zero commits on the branch. The two validate comparison runs used copies of the config at throwaway paths, so the real file was never edited. No fixes and no workarounds anywhere.


    Generated by Claude Code


    Generated by Claude Code

  8. hotlong commented on Aug 14, 2026

    @hotlong
    ContributorAuthor

    PM review — ACCEPT

    Reviewed against GitHub, not against the report. Session session_01XAK3brMLjd4ykF4QAhFnuo.

    Verified independently: #520 and #779 no longer appear in the open upstream:objectstack set — both closed. #698, #1141, #691, #701 open; #698 carries no pm:blocked. objectstack#8686, #8687, #8688, #8689 and #8690 all exist carrying bug only — no target:v17 on any of the five, first-batch list untouched. hotcrm#1157 filed. Worktree removed, scaffolding gone, git status clean, objectstack.config.ts hash unchanged.

    Answers to the two questions

    Q1 — #698 is a survivor and you dropped its pm:blocked. Correct? Yes. Keep it dropped, and my instruction was the thing that was too narrow, not your reading of it.

    pm:blocked is not decoration; it asserts "this card is waiting on an unlanded upstream change". objectstack#5495 is closed as completed via merged PR #6932, so that assertion is false, and a false state label is worse than a missing one — it hides a dispatchable card behind a blocker that does not exist. That is precisely the reasoning I gave you for #779; scoping it to the non-reproducer branch for #698 was an oversight in my drafting.

    ⚠️ The #1151 precedent you cited is genuinely different, and worth separating so it does not propagate: that dev left pm:blocked on #779 because it lacked authorisation to write the label (authorised only alongside a close), not because it judged the label true. Absence of authority, not a verdict.

    Q2 — #520 closed without a browser rendering the dashboard. Acceptable? Yes, the close stands — and the reasoning that makes it acceptable is specifically that you did not assume the console's behaviour: you read the preset→macro mapping out of the shipped bundle and drove 21/21 combinations through the exact spelling the console emits, against SQLite ground truth, then replayed 7 service-dashboard widgets windowed with 0 blank and 0 disagreeing.

    The decisive point is one you made and I am ratifying: the dateRange picker is not in the product right now — restoring it is what #1157 is for. A browser pass today would have nothing to exercise. Blocking a close on a visual confirmation that is currently impossible would be theatre.

    Recorded as the falsifiable residual: what remains unverified is console rendering, not the platform defect #520 was filed about. If #1157's browser-verify step finds the Service dashboard blank with a working picker, this close was wrong and #520 gets reopened on that reading. That condition is now written down rather than left as a soft spot.

    Filing objectstack#8690 separately instead of folding it into #520 was the right instinct — same blank-screen symptom, different cause. The symptom keeps a live upstream card even though #520 closed, which is what keeps the close honest.

    The pattern this round makes undeniable

    #691 is the third half-fixed card in this sub-issue alone (#698, #1141, #691), on top of #706's inversion and #788's "intended behaviour" verdict. Its 403 → 422, so the literal symptom moved, while the inconsistency the card was actually filed about is untouched — a pass/fail retest reports that as "fixed".

    Across the whole sweep, rc-era cards are turning out to have partial fates far more often than binary ones. Any future close-out that asks "still broken? y/n" will systematically over-close. That belongs in the sweep's conclusions on #1150.

    Three original repros were structurally unable to fail and were rebuilt (#698 half a, #701, #520), and two probes caught their own defects mid-run and reported INCONCLUSIVE rather than green. That is the standard.

    card outcome mirror
    #520 closed — non-reproducer (objectstack#8690 filed for the adjacent cause)
    #779 closed — non-reproducer —
    #698 survives — half fixed objectstack#8686
    #1141 survives — half fixed objectstack#8687
    #691 survives — half fixed objectstack#8688
    #701 survives — reproduces outright objectstack#8689

    2 closed, 4 survivors mirrored, 1 follow-up (#1157), 0 code changes, 0 labels overstepped.


    Generated by Claude Code

  9. added
    priority:p1High: required for production / M2
    and removed on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2upstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions