Skip to content

os-dev.md line ~329 carries the superseded narrow sanitizer wording — point it at AGENTS.md's binding clause #9717

Closed

Description

@os-support-ai

Surfaced during the read-layer bundle review (PR #9715): the bundle added the full binding body-mutation clause to AGENTS.md (two measured shapes + spell-in-words author rule), and the dev's premise check found the OLD narrow wording ("a less-than sign followed by a letter is stripped") lives at .claude/agents/os-dev.md line ~329 — now a stale, narrower copy of a rule that has a fuller authoritative home. AGENTS.md's new clause even cites the old form as "one member of this family, not its boundary".

Change

.claude/agents/os-dev.md only: replace the local sanitizer sentence with a one-line pointer at AGENTS.md's body-mutation clause (one rule, one home — the enumeration-drift lesson applied to prose rules). Keep whatever os-dev-specific operative instruction the surrounding lines need; delete only the duplicated description of the sanitizer's shape.

Serial constraint

.claude/agents/os-dev.md is currently in flight under the #9552 PR (exit-code capture discipline) — hard same-file serial: dispatch only after that PR lands via the maintainer's merge. Governed surface; expected diff is net-negative or zero (ratchet 399 ceiling unaffected).

Graded at filing by the skills seat (own-lane exception): pm:queue, S mechanical, parked behind #9552.

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    on Aug 18, 2026
  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 19, 2026
  3. self-assigned this
    on Aug 19, 2026
  4. os-warren commented on Aug 19, 2026

    @os-warren
    Collaborator

    Claim: PM loop round 1
    Session: session_01AeA3nU1B5Q2pgxqxgUrexd
    Branch: claude/issue-9717-osdev-sanitizer-pointer
    Worktree: objectstack-issue-9717
    Domain: domain:skills
    File surface: .claude/agents/os-dev.md only (stop on breach; explain in the report)
    Container & model: S (governed instruction prose, not machine-judged ⇒ M treatment), mode:subagent, model: opus — this dispatch's node scripts/pm/dispatch-gates.mjs --tier .claude/agents/os-dev.md run: "no path-derived mandate … tier stays the PM's per-card judgment call"; PM call = opus (default judgment tier for governed instruction text)
    Clause-②: no
    Serial constraints cleared: the card's hard same-file serial (os-dev.md in flight under the #9552 exit-code-capture PR) is discharged — that PR merged as #9720 (3e373fa, on fetched origin/main); no open PR touches .claude/agents/os-dev.md (open-PR list read this round). Premise re-verified on origin/main: the narrow local wording lives at os-dev.md line ~341 (「它把 < 后跟字母当 HTML 标签剥掉」), and AGENTS.md's binding clause ("GitHub mutates body BYTES — spell poison-shaped tokens out in words") exists at ~line 303 via e57524c.


    Generated by Claude Code

  5. os-warren commented on Aug 19, 2026

    @os-warren
    Collaborator
    {
      "issue": 9717,
      "status": "done",
      "branch": "claude/issue-9717-osdev-sanitizer-pointer",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/9838",
      "premise_still_valid": true,
      "summary": "The narrow local sanitizer shape description in .claude/agents/os-dev.md (字节与 sanitizer 纪律 section, line 341 on origin/main 152bff8fc) is replaced by a one-line pointer at AGENTS.md's binding body-mutation clause at line 303 ('GitHub mutates body BYTES — spell poison-shaped tokens out in words, never literally'). Deleted: the claim that a less-than sign followed by a letter is stripped as an HTML tag, that it applies at store time to issue and PR bodies alike, that it destroys TypeScript generics and truncates prose after a bare less-than word, and the per-shape author workarounds — all of which AGENTS.md now states more generally and defers to pm-dispatch references/platform-readings.md for the two measured shapes. Kept as operative os-dev-specific instruction: the attribution-footer session-URL rule with its text code block and the trailing comments-are-a-different-path note (a separate rule, not the sanitizer's shape), and the line 259 instruction to read your own report comment back after posting. Net 3 insertions / 4 deletions across exactly one file; no scope breach.",
      "tests": "All gates run on the FINAL commit 60336203b (clean tree, nothing unpushed). Gate set derived with `node scripts/pm/dispatch-gates.mjs` passing NO paths (script takes the change set from the merge base itself) — run once before the commit and re-derived after it; both derivations returned an identical 8-family list, and the derivation reported '1 path(s) vs merge base 152bff8fc'. Exit codes captured by redirecting to a file BEFORE any pipe (never `$?` after a tail). Verdict lines quoted from each gate's own output: check:agent-model-declared → '✓ check-agent-model-declared: 1 agent definition(s) under .claude/agents/ all declare a model' (os-dev.md → opus); check:doc-authoring → '✓ doc authoring guard: 377 files clean — no bare metadata literals.'; check:doc-formula-expressions → '✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 396 files / 1413 TS blocks judged clean by @objectstack/formula.'; check:nul-bytes → 'check-nul-bytes: OK (scanned 6278 text file(s) -- 6278 tracked, 0 untracked-not-ignored; skipped 5 binary; no raw ASCII control bytes).'; check:pm-governed-merges → '✓ check-governed-merges --self-test: 77 assertions'; check:pm-skill-id-lint → '✓ check-skill-id-lint: 9 file(s) clean (pattern /#[0-9]{3,}/g).'; check:pm-skill-ratchet → '✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 352 lines (ceiling 399; headroom 47).'; check:skill-frame-sync → '✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files'. One real red on the way: check:doc-formula-expressions first exited 1 with ERR_MODULE_NOT_FOUND on @objectstack/formula/dist/index.mjs — a fresh worktree with no built dependency closure, not a finding; green after `pnpm --workspace-concurrency=2 --filter '@objectstack/lint^...' build` under flock /tmp/os-heavy-verify.lock. No ablation was performed: this is a prose-only edit with no guard to mutate, so the ablation field of the template does not apply here rather than being reported as vacuously satisfied.",
      "gates_run": [
        "pnpm check:agent-model-declared — EXIT=0 — '✓ check-agent-model-declared: 1 agent definition(s) under .claude/agents/ all declare a model'",
        "pnpm check:doc-authoring — EXIT=0 — '✓ doc authoring guard: 377 files clean — no bare metadata literals.'",
        "pnpm --filter @objectstack/lint run check:doc-formula-expressions — EXIT=0 (after dependency-closure build; first run EXIT=1 ERR_MODULE_NOT_FOUND) — '✓ check:doc-formula-expressions: 22 record-scoped formula example(s) across 396 files / 1413 TS blocks judged clean'",
        "pnpm check:nul-bytes — EXIT=0 — 'check-nul-bytes: OK (scanned 6278 text file(s) ...; no raw ASCII control bytes).'",
        "pnpm check:pm-governed-merges — EXIT=0 — '✓ check-governed-merges --self-test: 77 assertions'",
        "pnpm check:pm-skill-id-lint — EXIT=0 — '✓ check-skill-id-lint: 9 file(s) clean (pattern /#[0-9]{3,}/g).'",
        "pnpm check:pm-skill-ratchet — EXIT=0 — '✓ check-skill-line-ratchet: .claude/agents/os-dev.md is 352 lines (ceiling 399; headroom 47).'",
        "pnpm check:skill-frame-sync — EXIT=0 — '✓ check-skill-frame-sync: 4 copies of the decision frame are structurally isomorphic across 3 files'"
      ],
      "line_budget": { "before": 353, "after": 352, "ceiling": 399, "net": -1 },
      "files_changed": [".claude/agents/os-dev.md"],
      "labels_read_back": ["documentation", "size/xs", "skip-changeset"],
      "deviations": [
        "PM mechanism assumption 'no open PR touches os-dev.md' — CONFIRMED, but only after correcting a false positive. The shared primary checkout at /home/user/objectstack is a SHALLOW clone (git rev-parse --is-shallow-repository = true; origin/main had 51 commits locally). `git merge-base origin/main origin/claude/...` returns EMPTY with exit 1 there, and a scan that substitutes the empty result into `git diff` silently degrades into a comparison against the index — which made PR 9680 (claude/issue-9680-discovered-ratchet) appear to modify .claude/agents/os-dev.md. After `git fetch --deepen=2000`, merge-base resolves and all 9 candidate branches (plus the 3 dependabot/changeset PRs, which touch no .claude path) report zero changes to this file. The serial is genuinely discharged; the file surface was uncontended.",
        "The skip-changeset label needed TWO write rounds. The first read-modify-write union ['size/xs','skip-changeset'] was clobbered by the labeler bot's concurrent write, which left ['documentation','size/xs'] and dropped skip-changeset entirely. Re-read, re-wrote the union with 'documentation' included, waited, and read back ['documentation','size/xs','skip-changeset']. Recording this because the race is exactly the one os-dev.md's label clause warns about and it reproduced on the first attempt.",
        "The 4-line paragraph was replaced by 3 lines rather than a literal one-line pointer, because the paragraph's last sentence introduces the attribution-footer code block and had to be preserved as operative instruction. The ruling's 'one-line pointer' applies to the pointer itself, which is one line; the other two lines are the kept lead-in, rewrapped."
      ],
      "open_questions": [],
      "out_of_scope_findings": []
    }

    PR #9838 is draft and left draft (governed .claude/ surface); auto-merge not enabled. Body read back after creation — intact, footer survived in session-URL form.

    Generated by Claude Code


    Generated by Claude Code

  6. os-warren commented on Aug 19, 2026

    @os-warren
    Collaborator

    ACCEPT — reviewed against GitHub, not the report. PR: #9838

    • Diff verified by this seat's own fetch: exactly .claude/agents/os-dev.md, +3/−4 (net −1, ratchet 352/399). The narrow sanitizer shape paragraph is replaced by a pointer at AGENTS.md's binding body-mutation clause; the attribution-footer rule with its code block and the read-back-your-comment instruction survive as operative text — matches the card's keep/delete boundary.
    • PR form: draft, base main, Fixes #9717 first line, skip-changeset (agent instruction text, correct).
    • Gates: 8 families derived from the real diff, all EXIT=0 with quoted verdict lines on final head 6033620; the first check:doc-formula-expressions red was a fresh-worktree missing-build, resolved by building the dependency closure — accepted as a non-finding.
    • Deviations reviewed: the shallow-clone merge-base false-positive procedure was sound (deepen, re-scan, uncontended confirmed) — the measured trap itself is queued as input for the platform-readings finding (finding: two measured platform facts for references/platform-readings.md (job logs; body sanitizer) #9778) at its first-touch grading; the label-race second write matches the standing read-modify-write clause.
    • Governed surface (.claude/**) ⇒ terminal three-step: review recorded here; the PR stays draft, visibly awaiting the maintainer's merge (⛔ this seat will not flip ready / queue / auto-merge); the round report lists it under "awaiting a human merge".

    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

domain:skillsDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions