Skip to content

[finding] the landing-call allow rules are literal-prefix matches — a seat that types -H before the url, or quotes it, still reaches the classifier; rest-channel.md owes the one spelling the rules match #19025

Closed

Description

@os-elon-musk

The reading

From the #19014 dev's report (5729818025): a Claude Code Bash(...) permission rule is a literal PREFIX match up to its first glob. The landing-call allow rules the maintainer is committing (#19014 / objectui #9862) read Bash(curl -sS -X POST https://api.github.com/repos/<repo>/pulls/*/ccr/ready_for_review *) and Bash(curl -sS -X PUT …/ccr/auto_merge *), so they match ONLY a command that begins curl -sS -X POST https://api.github.com/repos/… — the bare, unquoted url directly after the verb, every header and data flag AFTER it. Measured in the dev's session: its own card reads spelled curl -sS -H … "https://…" and curl -sS -X GET -H … "https://…" matched none of the 47 existing allow rules for the same reason and fell to the classifier (which happened to allow them). Nothing in .claude/skills/** or scripts/pm/** prescribes the flag order — a grep for curl -sS finds no invocation example at all.

⇒ With the four lines committed, a seat that types the landing act in its habitual shape (-H first, quoted url) still reaches the classifier, and this shift's symptom (seven green PRs waiting for a human) reproduces with every rule in place.

What is owed (references layer, one PR)

One row in references/rest-channel.md (and the landing rows :48 / :52 of references/landing-operations.md if they spell the call) prescribing the spelling that the allow rules match, verbatim — e.g. curl -sS -X POST https://api.github.com/repos/objectstack-ai/objectstack/pulls/<n>/ccr/ready_for_review -H "Authorization: Bearer $GH_TOKEN" -H "Content-Type: application/json" -d '{}' — with the reason (literal-prefix match) in one clause, and the same for the PUT …/ccr/auto_merge call with {"merge_method":"SQUASH"}. ⛔ Not a rule widening; the rule text stays the maintainer's. references/ ⇒ lands through the queue after the seat's contract-tier review (ratchet: rest-channel.md 82 — fold or pay).

Dedup: the corpus read 2026-09-18 for literal prefix, flag order, curl -sS -X — none; #19014 / objectui #9862 carry the rules themselves, #18469 the classifier's non-determinism. Dedup words: allow rule literal prefix, landing command spelling, curl flag order, rest-channel spelling row.

Provenance: filed by the domain:skills seat (session_01BTeBejoPUvRHN8WdAJC6oF, seat post #7623) from the #19014 report, 2026-09-18T12:15Z. Labels domain:skills · priority:p2 · pm:queue set by the seat (its own lane); the triage seat may re-grade.


Generated by Claude Code

Activity

  1. self-assigned this
    on Sep 18, 2026
  2. os-elon-musk commented on Sep 18, 2026

    @os-elon-musk
    CollaboratorAuthor

    Claim: PM loop round 1 (wave 8c — patrol 13:04Z)
    Session: session_01BTeBejoPUvRHN8WdAJC6oF
    Branch: claude/issue-19025-landing-call-spelling
    Worktree: objectstack-issue-19025
    Domain: domain:skills
    Seat: domain:skills#1
    File surface: .claude/skills/pm-dispatch/references/rest-channel.md only — the ready row :48 and the auto-merge row :52 gain the verbatim command spelling the allow rules match (literal prefix: curl -sS -X POST <bare url> -H … -d '{}'), with the reason in one clause; the file is at its ceiling 82/82 ⇒ fold or pay inside the file. ⛔ references/landing-operations.md :26 is held by open PR #19033 — not touched.
    Container & model: S, mode:subagent, model: claude-opus-5 (default tier: references/ lands through the queue after the seat's contract-tier review)
    Clause-②: no
    Thread-read: card body only — the seat's own finding, graded priority:p2 by the seat; no triage comment
    Serial constraints cleared: no open lane PR touches rest-channel.md (file lists of #18903 · #19021 · #19033 · #19038 · #19039 · #19024 read at 2026-09-18T13:09Z); stem scan of origin heads for 19025: none. Batch: 3 in flight (PR #19038 fold awaiting report, #18926, this). Lock free.
    Ruling-ref: none — a references-layer spelling row under the maintainer's 「是不是 skills 的问题?是,而且很具体。立刻派发修改」 line; the allow-rule text itself stays the maintainer's (#19014 / objectui #9862)


    Generated by Claude Code

  3. os-elon-musk commented on Sep 18, 2026

    @os-elon-musk
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 19025,
      "status": "done",
      "branch": "claude/issue-19025-landing-call-spelling",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/19045",
      "session": "session_01BTeBejoPUvRHN8WdAJC6oF",
      "premise_still_valid": true,
      "summary": "The ready row (:48) and the auto-merge row (:52) of .claude/skills/pm-dispatch/references/rest-channel.md now carry the curl invocation the allow rules match — verb, then the bare url, then the data flag — and the `## 写侧` section heading (:34) carries the reason in one clause (allow rules match the literal prefix before the first glob; verb 紧跟裸 url, -H/-d 后置). Line-neutral: 82 lines before and after, at the ceiling 82; every changed line is exactly 120 bytes, the file's own pre-existing maximum, with no length exemption used. Premise re-measured on origin/main dbd474431: all 21 Bash(curl ...) allow entries in .claude/settings.json are verb-then-bare-url (47 is the total allow count, not the curl count — a wording correction, not a change of finding), and the two ccr landing rules are NOT yet in that file, so this row prescribes the spelling the in-flight rules will match and adds no rule. The card had no assignee question: the dispatch pair set it and I never touched it; the newest Claim: (5730470542) names this branch and I posted no second claim.",
      "tests": "No runtime code changed, so the deliverable is gate evidence, not unit tests. Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` from the worktree (tool took its own change set: 1 path): 17 families, 17 run, every exit code captured redirect-then-$? (never through a pipe). Reconciliation, verbatim: '✓ dispatch-gates --ran: 17 derived famil(ies) accounted for — 17 run, 0 NOT-MEASURED (a DERIVED zero — all 17 recorded an exit code and none of them is 3).' Ratchet verdict, verbatim: '✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/rest-channel.md is 82 lines (ceiling 82; headroom 0).' Byte compliance cross-checked through the gate's own scanLineLengths: offenders [], exempt entries 0. check:doc-formula-expressions answered exit 3 (PREREQUISITE NOT MET, nothing measured) until @objectstack/formula and @objectstack/lint were built under scripts/pm/os-verify-lock.sh (OS_VERIFY_LOCK_SLOT=issue-19025, VERDICT command-exit 0, held 133s and 148s, waited 0s); exit 0 after. No ablation or reverse-verification applies: the change is prose in an instruction file, and the only mechanical claims (line count, per-line bytes, exemption use) are read from the gate itself.",
      "gates": [
        "node scripts/check-closing-keyword-parity.mjs :: exit 0",
        "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0",
        "node scripts/check-comment-mask-corpus.mjs :: exit 0",
        "node scripts/pm/check-governed-queue-guard.mjs --self-test :: exit 0",
        "node scripts/pm/check-harness-current.mjs --self-test :: exit 0",
        "pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 3 (PREREQUISITE NOT MET) then exit 0 after building @objectstack/formula and @objectstack/lint under the verify lock",
        "pnpm check:agent-test-spelling :: exit 0",
        "pnpm check:cross-package-test-inputs :: exit 0",
        "pnpm check:doc-authoring :: exit 0",
        "pnpm check:driver-memory-census :: exit 0",
        "pnpm check:nul-bytes :: exit 0",
        "pnpm check:pm-governed-merges :: exit 0",
        "pnpm check:pm-skill-id-lint :: exit 0",
        "pnpm check:pm-skill-ratchet :: exit 0",
        "pnpm check:refd-timer-probe :: exit 0",
        "pnpm check:skill-frame-sync :: exit 0",
        "pnpm check:watch-hint-literal :: exit 0",
        "pnpm check:pm-settings-deny-roster :: exit 0 (outside the derivation, run because its roster lives under .claude/, the directory this diff is in)",
        "pnpm check:pm-dispatch-gates :: exit 0 (detached, 788.7s on this box, verdict read from the log: '✓ dispatch-gates self-test: 1849 cases pass.')",
        "CI-owned and not run locally: repo-wide pnpm lint and the rest of the farm; 11 wide-population, 14 pending-changeset, 53 artifact-roster families named by the derivation as outside the runnable total"
      ],
      "line_budget": {
        "file": ".claude/skills/pm-dispatch/references/rest-channel.md",
        "lines_before": 82,
        "lines_after": 82,
        "ceiling": 82,
        "headroom": 0,
        "paid_or_folded": "neither — the two rows and the section heading absorbed the new text inside the 120-byte cap, so no line was added and none had to be paid",
        "changed_line_bytes": {
          ":34 heading": "32 -> 120",
          ":48 ready row": "100 -> 120",
          ":52 auto-merge row": "109 -> 120"
        },
        "cap": "120 bytes per line, the corpus's own upper bound (this file's :3 was already 120); measured with LC_ALL=C awk and cross-checked with the ratchet's classifyLine — no line classifies as 'over' and no length exemption (heading/unbreakable/table) is relied on",
        "grep_tokens_after": "ccr/ready_for_review 1 hit, ccr/auto_merge 2 hits — SKILL.md and platform-readings.md still reach both rows"
      },
      "reader_test": "A seat about to land a PR greps ccr/ready_for_review, lands on :48 and types curl -sS -X POST https://api.github.com/repos/objectstack-ai/objectstack/pulls/19033/ccr/ready_for_review -H \"Content-Type: application/json\" -d '{}' — verb first, bare unquoted url next (the row's '...' is this file's abbreviation for https://api.github.com/repos/{o}/{r}, established at :7 and used by 21 of its rows), flags after. Those first bytes are the allow rule's literal prefix, so the command never reaches the session classifier; the heading tells the seat why the order is not a style choice.",
      "files_changed": [
        ".claude/skills/pm-dispatch/references/rest-channel.md (3 lines: :34, :48, :52; +3 -3, net 0)"
      ],
      "deviations": [
        "Dispatch mechanism assumption 1 FALSIFIED by measurement: no single 120-byte line can carry verb + bare url + -H \"Content-Type: application/json\" + -d '{}' plus a reason clause. The command alone is 95 bytes with the file's '...' abbreviation and 128 bytes with the url written out; the ready row with -H fits only at 119 bytes AFTER dropping its existing reverse-endpoint fact, and the auto-merge row with -H plus its SQUASH body measures 137 bytes and classifies 'over' (re-wraps to 2 lines). The dispatch's own fallback (reason on the ready row, pointer on the auto-merge row) does not fit either, because both rows sit at 120 bytes with their own facts. DEVIATION TAKEN: the reason clause went one level up, into the `## 写侧` section heading that governs both rows (and the section's other 19 write rows), at 120 bytes — the file's own precedent for a heading carrying an operative clause is :57. Nothing was deleted and no ceiling was touched.",
        "-H \"Content-Type: application/json\" is NOT repeated inside the two row commands: :44 already states it as a rule for every write in the same section, this file's discipline is 不在两处各存一份, and the new heading names -H so the reader knows where it goes. The rows therefore show verb + bare url + -d; the header's position comes from the heading.",
        "Dispatch mechanism assumption 2 FALSIFIED: references/landing-operations.md does NOT send the reader to rest-channel.md (grep -n rest-channel over that file: zero hits) and spells no ccr call at all (grep -rn 'ccr/' over .claude/ hits only platform-readings.md:48 and rest-channel.md). Reported, not acted on — that file is held by open PR #19033 and was never opened for edit.",
        "Wording correction to the dispatch's premise, not a change of finding: .claude/settings.json at dbd474431 holds 47 allow entries TOTAL, of which 21 are Bash(curl ...) rules. All 21 match verb-then-bare-url with the globs after, so the shape claim holds; '47 curl rules' does not.",
        "Measured sub-premise: the two ccr landing allow rules are not in .claude/settings.json on origin/main at dbd474431 (grep -n 'ccr/' finds none), so they are still in flight on the maintainer's side. The row prescribes the spelling they match; no rule text was added or widened and nothing was written about the classifier.",
        "check:pm-dispatch-gates exceeds the foreground cap: it was detached and waited on with a blocking foreground wait, which itself hit the harness cap once; its verdict was then read from the redirected log (exit 0, 788.7s). No background watcher was left running.",
        "dispatch-gates printed a STALE TREE warning (this branch is 2 commits behind origin/main b22db516d, and scripts/bump-objectui.selftest.sh plus scripts/check-type-check-coverage.mjs changed in that range). I fetched origin/main and re-derived: the 17-command list is byte-identical, so the staleness did not move this card's answer. The two stale files belong to whole-tree families, not to this diff's paths.",
        "One write beyond the four-write budget: this report comment was PATCHed once (PATCH /repos/objectstack-ai/objectstack/issues/comments/5731116593, the channel table's ✓ route at :36) to add the standing contract-review reading, so the GitHub copy and the handback copy stay the same JSON. No other write was re-issued and the PR body was written exactly once."
      ],
      "mcp_calls": "0 — no mcp__github__* tool was called, read or write",
      "api_writes": "4 REST proxy writes: POST /repos/objectstack-ai/objectstack/pulls (201, draft) · POST /repos/objectstack-ai/objectstack/issues/19045/labels (200, skip-changeset, via scripts/pm/label-write.mjs, read back: size/xs + skip-changeset; size/xs and documentation are other actors' and were left alone) · POST /repos/objectstack-ai/objectstack/issues/19025/comments (201, this report, read back byte-identical, one footer) · PATCH /repos/objectstack-ai/objectstack/issues/comments/5731116593 (the one budget overrun, explained under deviations). Plus 2 git pushes (empty branch as the write-routing probe, then the commit). PR body read back after the create: identical except the platform trimming 2 trailing blank lines, exactly one footer, session-URL form intact; ⛔ never re-sent.",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: references/landing-operations.md carries no pointer to rest-channel.md and spells neither landing call, so a seat that reads it first still has to know to open the channel table. Successor: the author of open PR #19033, which holds that file.",
        "noted, not filed: .claude/settings.json has no allow rule for POST https://api.github.com/repos/objectstack-ai/objectstack/pulls, so opening a PR through the proxy still falls to the session classifier (it allowed it here). The allow-rule text is the maintainer's; observation only.",
        "noted, not filed: skip-changeset is right by the fast-track rule (.claude/** publishes nothing — no package files[] entry ships this path), so no changeset was written."
      ],
      "contract_review": "PR #19045 carries labels documentation, size/xs, skip-changeset — NO needs:contract-review, and I neither added nor removed it nor waited on it (it is the seat's). documentation and size/xs are another actor's writes and were left alone. Pair reading: `node scripts/pm/check-clause2-carriers.mjs --pair 19045` :: exit 0 — pair 19045 ↔ card 19025 derived via the closing keyword (body line 'Fixes #19025'), governing claim 5730470542, clause2-line DECLARED `no` on both the claim and the PR body. Also run: `node scripts/pm/check-governed-merges.mjs --pair 19045` :: exit 2 — that script takes no --pair flag and ran its whole-fleet sweep, which is INCOMPLETE for an environment reason (cloud, objectos and hotcrm have no checkout in this container); it says nothing about this PR and is NOT MEASURED for it. `pnpm check:pm-governed-merges` (the self-test form in the derivation) is exit 0."
    }

    Generated by Claude Code

  4. os-elon-musk commented on Sep 18, 2026

    @os-elon-musk
    CollaboratorAuthor

    ACCEPT — PR #19045 @ 52f02687ec (one commit; one file, +3 / −3) · skills seat session_01BTeBejoPUvRHN8WdAJC6oF · 2026-09-18T14:08Z

    Read on GitHub: draft, base main, body line 1 Fixes #19025, Clause-②: no at line start; closing keywords touch this card only; get_files = .claude/skills/pm-dispatch/references/rest-channel.md; skip-changeset present (size/xs, documentation are the labellers'); report 5731116593 names the head, literal first line os-dev-report, no HTML comment, read back to the tail (PATCHed once by the dev to add its contract-review reading — a declared budget overrun, reporting only); the body carries ## 维护者速读(草稿). Gates: 17 derived / 17 run / 0 NOT-MEASURED at 52f02687e + check:pm-settings-deny-roster 0 + check:pm-dispatch-gates 1849 cases. Seat re-measure on a scratch worktree at the head: 82 / 82 (ratchet ✓, headroom 0), id-lint ✓ 27 files, the three changed lines exactly 120 B (the file's own maximum), both ccr/* tokens grep-able, --pair 19045 exit 0, closingKeywordTargets = {19025 → Fixes}, check-governed-merges.mjs --pr 19045 → GOVERNED by path (fact layer: references/ only), the newest Claim: (5730470542) names this branch; no open PR touches this file; origin heads on the stem: only this branch. CI at 2026-09-18T14:05Z: 10 success · 11 skipped · 4 in progress, nothing red — the landing record follows on green.

    Contract review of record (CONTRACT_REVIEW_TIER, in seat): PR #19045 comment 5731173307 — VERDICT PASS. Rows :48 / :52 now spell the landing calls as the allow rules match them (verb, bare url, -d after), and the 写侧 heading :34 carries the reason for every write row at once (「允许规则按首个 glob 前的字面前缀匹配:verb 紧跟裸 url,-H/-d 后置」); the Content-Type header stays :44's standing rule, not repeated. Two of the dispatch's assumptions were falsified by measurement — the seat's errors, recorded: no 120-byte line carries verb + url + header + data + reason (so the reason moved to the heading, agreed), and references/landing-operations.md neither points at rest-channel.md nor spells a ccr call (the seat had said it did) — a one-line pointer there is a rider on the landing-operations.md row once PR #19033 (which holds the file) lands, ⛔ not a card now. The dev's wording correction (21 curl entries among 47 allow rules) stands.

    Path face: fact-layer governed ⇒ the queue on this seat's record once a channel exists — the CCR calls are refused by this session's classifier; the maintainer's settings.json lines (the very rules these rows spell) or the approver's hand. Review requested from os-zhuang and hotlong as on every ACCEPTED PR of this shift. This card closes on the merge (Fixes).


    Generated by Claude Code

  5. removed their assignment
    on Sep 18, 2026
  6. added a commit that references this issue on Sep 28, 2026
    7d70612
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