[WIP] Fix error in step four of the action run - #5
Merged
huangyiirene merged 2 commits intoJan 18, 2026
Merged
huangyiirene merged 2 commits into
huangyiirene merged 2 commits into
Conversation
Regenerate package-lock.json to fix npm ci failure in CI workflow. Updates @types/node from 12.20.55 to 25.0.9 and adds missing undici-types dependency. Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
huangyiirene
marked this pull request as ready for review
January 18, 2026 09:25
Copilot stopped work on behalf of
huangyiirene due to an error
January 18, 2026 09:25
hotlong
added a commit
that referenced
this pull request
May 20, 2026
Closes gap #5 from the production-readiness review: zero-dependency observability hooks that let hosts plug Prometheus / OTel / Sentry without the framework taking a hard dep on any of them. Three pluggable primitives (all default to no-op, zero overhead): - MetricsRegistry — counter/histogram/gauge contract; NoopMetricsRegistry default + InMemoryMetricsRegistry for tests. Canonical names exposed via RUNTIME_METRICS constant. - ErrorReporter — captureException(err, ctx) contract; called only for 5xx responses (4xx are tracked via the metrics counter, intentionally NOT reported, to keep APM signal:noise high). NoopErrorReporter default + InMemoryErrorReporter for tests. - Request correlation — extractRequestId / generateRequestId / resolveRequestId; X-Request-Id is validated against ^[A-Za-z0-9._:-]+$ ≤200 chars so a malicious caller cannot inject headers or pollute logs. Also parseTraceparent / formatTraceparent for W3C Trace Context interop. Wired into createDispatcherPlugin via instrumentRouteHandler() which wraps every server.get/post/delete handler with: - request-id propagation (req.requestId + X-Request-Id response header) - http_requests_total{method,route,status} counter - http_request_duration_ms{method,route} histogram - http_request_errors_total{method,route} on thrown errors - error reporter on 5xx, both for thrown errors AND for the common case where the handler catches and calls errorResponseBase (side-channel via res.__obsRecordedError) - reporter failures are swallowed so they never mask the original error The IHttpServer wrapping is a Proxy that intercepts only the three verb methods — no signature changes on the 50+ existing handlers. docs/OBSERVABILITY.md ships the full production recipe: Prometheus prom-client adapter, OTel adapter, Sentry adapter, Datadog adapter, cardinality caveats, go-live checklist. 52 new tests (21 request-context, 9 metrics, 6 error-reporter, 16 instrument). 280 total runtime tests; 4 pre-existing failures unrelated. tsc clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
xuyushun441-sys
pushed a commit
that referenced
this pull request
May 22, 2026
Introduces an opt-in path in ObjectStackProtocolImplementation.saveMetaItem that writes overlay metadata through SysMetadataRepository.put instead of the raw engine, so writes append to the change-log and emit HMR seq events. Behavioural changes (all behind options.useRepositoryWritePath / OBJECTSTACK_USE_REPOSITORY_WRITE_PATH=1): - saveMetaItem request gained optional parentVersion (If-Match) and actor fields. ConflictError -> 409 metadata_conflict. - Plural type aliases (views, dashboards, ...) normalized to singular before the repo's overlay-allowlist gate (rubber-duck #5). - Object-registry mutation moved AFTER successful put() so a conflict does not leave the in-memory registry stale (rubber-duck #3 invariant test added). Repo/test-fake fixes uncovered by rubber-duck review: - SysMetadataRepository.put/delete now update/delete by row id because the engine's strict .update requires id or multi:true (rubber-duck #1). - sys_metadata.checksum column widened from 64 -> 71 chars to hold the sha256: prefix produced by hashSpec() (rubber-duck #2). - Three test fake engines extended to support both overlay-tuple and id-based where lookups. 333/333 objectql tests pass. Deferred to PR-10d.4: REST plumbing for parentVersion/actor (rubber-duck #6), race-window retry for omitted parentVersion (rubber-duck #4), default flag flip + legacy path removal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced May 25, 2026
Closed
Closed
This was referenced Jun 10, 2026
os-zhuang
added a commit
that referenced
this pull request
Jun 19, 2026
…antics Full hardening of the remaining items from review: - #5 MySQL/length: key _objectstack_sequences by a single key_hash (SHA-256 of object,tenant_id,field,scope) instead of a 4-column natural PK. The natural PK exceeded MySQL's utf8mb4 index-length limit (a certain CREATE TABLE failure) and bounded how long a {field} scope could be. The hash PK keys every dialect uniformly and lets scope be a generous non-indexed column. Legacy 3-column and interim {scope}-column tables are migrated in place; migration fails safe (fixed-prefix keeps working, a per-scope write errors actionably). - #1 scope ambiguity: confirmed NOT fixable by separating adjacent token boundaries — when two records render the same prefix they render the same visible number, so they MUST share a counter to stay unique (a separator would mint duplicates). Documented the semantics + the remedy (delimiter literal in the format), backed by tests. The compile lint already nudges authors toward unambiguous formats. - #6 width overflow: confirmed by-design — the pad width is a MINIMUM, the counter grows past it and never wraps (mainstream autonumber semantics). Documented + regression test, no throw (throwing would break legitimate high-count sequences). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang
added a commit
that referenced
this pull request
Jun 19, 2026
…ber formats (#2043) * feat(autonumber): date, {field} and per-scope counter reset for formats Tokenize autonumberFormat via a shared pure renderer in @objectstack/spec (parseAutonumberFormat / renderAutonumber) that both the engine fallback and the SQL driver call, so they emit byte-identical numbers (#1603 parity): - date tokens {YYYY}{YY}{MM}{DD}{YYYYMMDD} resolve the calendar day in the request's business timezone (ExecutionContext.timezone, ADR-0053; UTC fallback), threaded through new DriverOptions.timezone - {field} interpolation substitutes record values into the prefix - counter scope = rendered prefix before the sequence slot, so AD{YYYYMMDD}{0000} resets daily, {section}{island_zone}{000} numbers per group, {plan_no}{000} numbers per parent — one mechanism, no separate reset config Fixed-prefix formats (CASE-{0000}) render an empty scope and keep their single global counter. _objectstack_sequences gains a scope column (PK widened to object,tenant_id,field,scope); legacy 3-column tables migrate in place on first use, carrying existing counters to scope=''. * fix(autonumber): drop backtracking lookahead in seed scan (ReDoS) The empty-prefix legacy branch used /(\d+)(?!.*\d)/ to grab the last digit run, whose negative lookahead is a polynomial-ReDoS sink on stored values with many repeated zeros (CodeQL js/polynomial-redos, high). Replace both branches with the linear /\d+/g, preserving the last-digit-run semantics. * fix(autonumber): guard {field} interpolation footguns Add three guardrails on top of the {field}/date/per-scope autonumber work: - Empty interpolated {field} now throws (shared missingFieldValues helper) in both the SQL driver and the engine fallback, instead of silently collapsing the record into the wrong counter scope. - Build-time lint (objectstack compile): unknown / self-referencing {field} fails the build; an optional {field} warns to mark it required. - Legacy _objectstack_sequences PK-widen failure fails safe — fixed-prefix sequences keep working and a per-scope write raises an actionable error rather than an opaque DB primary-key violation at insert time. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(autonumber): hash-keyed sequence table; clarify scope & width semantics Full hardening of the remaining items from review: - #5 MySQL/length: key _objectstack_sequences by a single key_hash (SHA-256 of object,tenant_id,field,scope) instead of a 4-column natural PK. The natural PK exceeded MySQL's utf8mb4 index-length limit (a certain CREATE TABLE failure) and bounded how long a {field} scope could be. The hash PK keys every dialect uniformly and lets scope be a generous non-indexed column. Legacy 3-column and interim {scope}-column tables are migrated in place; migration fails safe (fixed-prefix keeps working, a per-scope write errors actionably). - #1 scope ambiguity: confirmed NOT fixable by separating adjacent token boundaries — when two records render the same prefix they render the same visible number, so they MUST share a counter to stay unique (a separator would mint duplicates). Documented the semantics + the remedy (delimiter literal in the format), backed by tests. The compile lint already nudges authors toward unambiguous formats. - #6 width overflow: confirmed by-design — the pad width is a MINIMUM, the counter grows past it and never wraps (mainstream autonumber semantics). Documented + regression test, no throw (throwing would break legitimate high-count sequences). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: os-zhuang <jack@objectstack.ai> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang
pushed a commit
that referenced
this pull request
Jul 8, 2026
…) (#2683) * feat(spec,lint): allow dropdown userFilters on object list views (#2679) Airtable-style quick-filter chips (`userFilters`, `element: 'dropdown'`) were blanket-suppressed on object list views ("views" mode) — omitted from `ObjectListViewSchema`, errored by the `validate` list-view-mode rule, and dropped at render. That over-corrected against ADR-0047 TL;DR #5 (data mode is meant to expose quick filters). Narrow the rule: an object list view MAY carry a `dropdown` (value-chip) userFilters; only the `tabs` preset style stays page-only, because the saved-view ViewTabBar already owns the tab-bar role (need presets on an object → use `listViews`). - spec: new `ObjectUserFiltersSchema` (element narrowed to dropdown/ toggle, tabs/showAllRecords omitted); `ObjectListViewSchema` extends `userFilters` back in with it. - lint: `validate-list-view-mode` flags `quickFilters` always, but `userFilters` only when `element: 'tabs'` / carrying `tabs`. - app-showcase: dropdown userFilters (status + health) on the default `showcase_project` list view. - docs: ADR-0047 amendment note + regenerated view reference. Companion objectui runtime change: objectstack-ai/objectui#2338. * docs(skills): note object list views allow dropdown userFilters, tabs page-only (#2679) * chore(spec): regenerate skill-docs + api-surface for ObjectUserFiltersSchema (#2679)
This was referenced Jul 10, 2026
This was referenced Jul 18, 2026
This was referenced Aug 30, 2026
This was referenced Aug 31, 2026
This was referenced Aug 31, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Sep 1, 2026
…ss, with the CPU inversion designed out (objectstack-ai#11915) The guard's only instrument was output flushes, measured at the wrong end of the pipeline: what it sees is whatever the last buffering layer chose to release. --log-order=stream closed one spelling of that; any future buffering layer re-opens it and kills a healthy suite deterministically on an innocent diff. Second signal: bytes every process in the wrapped group has passed to write(), read from /proc/<pid>/io (wchar) — the same quantity the guard already trusts, sampled at the SOURCE, before any buffering layer can hide it. Measured first, because the card's CPU direction does not survive contact (node 22, 2.5s sample, one process per shape): shape state dCPU(ticks) dwchar(bytes) idle hang (self-test objectstack-ai#4) S 0 0 sync-spinning hang (objectstack-ai#5) R 251 0 GC-thrash hang R 272 0 HEALTHY silent-but-working S 1 25,542 CPU does not merely fail to separate these shapes, it separates them BACKWARDS: the genuine hangs peg a core while the healthy suite the probe exists to protect is nearly idle, because it is I/O-bound — it is busy writing. wchar separates all four correctly. The probe is a confirming signal in one direction only. No output and no source-side bytes still kills at --stall-minutes with no added latency (idle and spinning hangs write nothing, so neither is ever deferred). No output but bytes still moving defers the kill, announced loudly — a live suite hidden by a buffering layer is a bug to fix, not to tolerate — and only as far as --stall-cap-minutes, after which the group dies under a distinct STALL-CAP verdict. That cap is what stops the probe turning "kills healthy suites" into "never fires on spin hangs", which is strictly worse. A cap <= the window is refused; an unreadable /proc/<pid>/io reports UNAVAILABLE and the guard behaves exactly as before. --stall-minutes is untouched. Claude-Session: https://claude.ai/code/session_015ahemw8RcTgqtxrj15PEZx Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Sep 2, 2026
This was referenced Sep 5, 2026
This was referenced Sep 6, 2026
This was referenced Sep 8, 2026
github-merge-queue Bot
pushed a commit
that referenced
this pull request
Sep 12, 2026
) Fixes #17366 ## The defect: a carrier a seat could write into and not get out of The clause-② declaration limb had one carrier — the `Clause-②:` line inside the card's governing `Claim:` comment — and repairing a line already written there was not an act every seat can perform. The MCP GitHub tool set carries no edit-an-issue-comment call; the claim protocol forbids a second `Claim:`; and this gate's own refusal forbids the checker filling the line in ("the declaration IS the judgement"). Three closed doors, and a seat that wrote the line as prose was left waiting for somebody outside the repository to retype it. That was measured five times in one shift across two roles, and the fifth instance was still holding a PR with 38 checks and 0 failures out of the queue when the card was filed. ## The fix: one correction comment, read by the same reader A dedicated comment whose FIRST line is a fixed key naming, in digits, the claim comment it corrects: ```text Clause-②-correction: 5642248126 Clause-②: no Session: `session_01MCLBsUgfykL74aU716rzVK` ``` The newest correction naming the card's governing claim supersedes that claim's declaration, in both directions — so a wrong VALUE is repaired by the same act as an unreadable one. The declaration inside it is read by the SAME `CLAUSE2_KEY_LINE` through the SAME `readClause2Line`, so what moved is WHICH COMMENT may carry the declaration, never what counts as an answer. That is the move #16304 already made when it asked a sibling CARD. Attribution is the `Session:` line the claim protocol already makes mandatory (SKILL.md 〈模板与表〉, 「session ID 不可省」, and 「`mode:subagent` 的 dev 与 PM 同会话同 ID」 — so the session is exactly the granularity of "the claiming seat"). A correction is attributed when its `Session:` equals the governing claim's. That is a DECLARED identity, never a verified one: the value is copyable text and this fleet writes under one GitHub login, so the comparison is on what the comments SAY — the same ceiling C4 already works at. ⛔ No branch of it may become a new one-way door, which is the defect being removed. A correction naming another comment, declaring a different session, carrying no `Session:` line, or carrying a prose declaration is IGNORED WITH A PRINTED REASON that names an act the claiming seat can perform. And a governing claim that carries no `Session:` line at all leaves nothing to compare: the correction APPLIES, with a note saying attribution could not be verified and why. Refusing there would have rebuilt the door one room over. The C2 remedy text was rewritten to name WHO can act and HOW, in three parts: the claim template in SKILL.md 〈模板与表〉 that already carries the literal `Clause-②: yes | no` line and should be copied rather than composed; the fact that an already-posted claim comment is not editable from every seat; and the one comment that repairs it. It replaces "add the line to that claim comment", which named an act the claiming seat may have no tool for. ## What deliberately did not move - **The accept set.** `CLAUSE2_KEY_LINE`, `readValueToken` and `CLAUSE2_VALUES` are untouched. The card's five measured prose spellings are pinned as negatives in the self-test. - **The exit register.** The correction is a new INPUT to C2, not a new verdict family. 0/1/2/3/4 keep their meanings and their numbers. - **`check-half-states.mjs`.** `CLAIM_COMMENT_MARKER` is still imported, not restated, and not widened. A correction is not a claim comment and never enters the claim pool. - **SKILL.md.** The template already carries the fixed line; this PR points at it and does not restate it. - **The writes.** This script still writes nothing, hangs no label, and reads no verdict word. ## Acceptance, all four from the card 1. **A seat writing per the template gets a machine-readable declaration.** Pinned by importing the reader over the template's own key with each value substituted, plus the new remedy text that sends the seat to the template rather than to a regex. 2. **The negative control holds.** All five measured spellings from the card's table are pinned as not-declared, from the line reader and from a claim comment. The `#1` spelling is reported as a SPELLING near miss; the `#2`–`#5` spelling reaches no pattern at all, because 条款② carries no `Clause` token — pinned as a measured fact. 3. **Self-solvability is pinned.** A card whose claim declaration is unreadable earns a C2 finding; adding ONE correction comment clears it, with the claim comment byte-identical across the two threads, no second `Claim:`, and the governing claim unmoved. Demonstrated end to end through the offline `--pair-json` path: `--pair` exit 4 with the broken claim, exit 0 with the one comment added. 4. **Ablation.** Deleting the correction reading reds 22 of 465 self-test cases (every criterion-3 case); deleting the template pointer and the who-can-act remedy reds 7 (criterion 1's new half). Both legs were mutated on disk, proved to have landed, then restored to a blob hash equal to HEAD's. ## Acceptance notes -⚠️ Measured and pinned as a CONTROL, not endorsed and not fixed here: the template line copied UNFILLED — `Clause-②: yes | no` — reads as a declared `yes`, because `readValueToken` takes the first token after the colon and treats the rest as the seat's argument. That is an instance of the population #17098 is already open against (a key-INITIAL DESCRIBING line read as a declaration), so it is ⛔ not filed again here. The case carries a pre-registered FLIP TRIGGER: when #17098 lands, the expectation becomes `kind !== 'declared'` and the case flips with it in that PR. ⛔ It is not to be deleted and its green today is not an endorsement. - The PR-body carrier of `Clause-②:` is read by `scripts/check-changeset-no-major.mjs`, not by this gate: `--pair` reads the PR side for LABELS (C1) only, and no `readClause2Line` call here takes a PR body. The card-side correction shape therefore has no PR-side counterpart to add, and the PR-body carrier is editable by the seat anyway — which is exactly the asymmetry the card names. - `check-scripts-symbol-anchors`, `check-self-test-wired` and `check-self-test-workflow-commands` all pass unchanged: the `check:pm-clause2-carriers` step in `lint.yml` already runs the self-test, and no second step was added. ## Gates, on head `dbbfbb596` `node scripts/pm/dispatch-gates.mjs --commands` derives 35 families for this one-path diff; all 35 ran and all 35 exited 0 (`--ran` reconciliation: "35 derived famil(ies) accounted for — 35 run, 0 NOT-MEASURED (a DERIVED zero — all 35 recorded an exit code and none of them is 3)"). Lint is the declared narrowing rather than the repo-wide run CI owns: the receiving population is `eslint.config.mjs`'s base block (`files: ['**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs}']`), `--format json` reports 1 file linted with 0 errors and 0 warnings, and the config "never enables type-aware linting (no `parserOptions.project`, no typed `@typescript-eslint` rules) for ANY file" (`eslint.config.mjs`, its own words) — so this diff cannot move the verdict on any file it does not touch. `node scripts/pm/check-governed-merges.mjs --test scripts/pm/check-clause2-carriers.mjs` prints "✅ NOT governed — ordinary queue landing applies". `--pair 17738` exits 0. --- _Generated by [Claude Code](https://claude.ai/code/session_01MCLBsUgfykL74aU716rzVK)_ --- _Generated by [Claude Code](https://claude.ai/code)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix package-lock.json sync issue causing CI failure
Problem: The GitHub Actions CI workflow fails at the "Install dependencies" step because
package-lock.jsonis out of sync withpackage.json. The lock file contains outdated dependencies (@types/node@12.20.55) that don't match the current requirements.Plan:
package-lock.jsonby runningnpm installnpm ciworks correctlyOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.