Skip to content

platform-readings records the body-PATCH footer behaviour by ROUTE; measured, it follows the SURFACE — the issues route on a PR doubles the footer #19390

Closed as not planned

Description

@huangyiirene

Path: none | fact table (.claude/skills/pm-dispatch/references/platform-readings.md — the PR grid :346 / :348 / :415 and the 队列 section) | family: lands in one PR with #19343 and #19404 | graded by domain:skills#2

What is wrong

references/platform-readings.md records the attribution-footer behaviour of a body PATCH by route. Measured today, it follows the surface. ⇒ a seat that follows the file's own prescription for editing a draft PR's body gets a doubled footer and no line in the file explains why.

The measurement

Taken 2026-09-20 on PR #19385 by the os-dev agent that owns the branch, and verified independently by the domain:engine PM seat by reading the stored body back:

reading
call PATCH /repos/objectstack-ai/objectstack/**issues**/19385 — the ISSUES route, on a pull request
sent 11 986 chars, exactly one footer (the session-URL form)
stored 12 044 chars — +58 bytes
what the +58 is a platform-appended bare footer under its own --- rule, with the sent one kept
footers now in the body 2 — …/code/session_01NcPS… at line 98, …/code at line 101
⭐ the draft bit untouched — read back GET /pulls/19385 ⇒ draft: true, state: open

⭐ The positive control — same verb, two surfaces, one hour apart

⚠️ Without this, "+58 was the footer" is an inference. With it, it is a contrast:

surface verb sent stored
PR #19385 pull request (via /issues/19385) PATCH 1 footer, 11 986 2 footers, 12 044 — +58
this card #19390 issue (via /issues/19390) PATCH 1 footer, whole block 1 footer, byte-for-byte

Same route prefix, same verb, same footer form, same hour, same credential. ⛔ The only variable is what the number addresses. ⇒ the append is a property of the surface.

⭐ Measured incidentally: this card's own body was re-sent to correct the section below, which made the control free. It also re-confirms :415 on the surface :415 was actually taken on.

⭐ What this confirms, and what it contradicts

Confirmed, and worth keeping: the issues route really does leave the draft bit alone. That is the whole reason the prescription exists (a bare PATCH /pulls carries the draft field, and :45 records a governed draft being pushed into the queue that way). ⛔ The prescription is not wrong about the thing it was written for.

Contradicted: :415 — 「issue 正文 PATCH 识别按整块:送全块或不送页脚都存回恰一条,已有页脚归一末尾不复制」. That reading was taken on a real issue and ⛔ does not transfer to a pull request reached through the issues route. What the PR surface does instead is exactly :346 — 「改侧 · 裸 REST PATCH /pulls 恒追加一条裸页脚并保留既有页脚,差恰 58 字节」 — the same +58, the same keep-and-append, through a different route.

⇒ the fact to record: the footer behaviour is a property of the SURFACE (pull request vs issue), ⛔ not of the ROUTE (/pulls vs /issues). Both existing lines are correct about what they measured; neither says which axis it varies on, and a reader combining them concludes the opposite of the truth.

⚠️ There is NO repair for an already-doubled body — the fix is a PRESCRIPTION for the next write

⛔ Corrected in place by the filer, because the first version of this card got it wrong and a false prescription in a card the taking lane will implement is worse than no card.

:348 reads 「同路送无页脚正文存回恰一条(平台裸形)⇒ 该格处方是不送页脚,⛔ 不是不重送正文」, and the filer first read that as a repair available to a body that already carries two. ⛔ It is not. AGENTS.md:432 is a ⛔ rule and outranks a references-file prescription:

Send the footer you want stored, read the body back after every write, and ⛔ never re-send a body that already carries an appended footer.

⇒ :348 governs the first write into that cell — send no footer and exactly one is stored. Once the platform has appended one, the body is ⛔ out of scope for re-sending at all, and the two footers stay. There is no second door.

⭐ So the trade is not between two repairs; it is between getting the first write right and living with the result:

  • before the write: send no footer through the issues route ⇒ exactly one, the platform's bare form. ⚠️ Note the cost so it is chosen rather than discovered — the session-URL footer AGENTS.md prescribes for PR bodies is then not in the body. It survives in the commit trailer (Claude-Session:), which is where a reader can still find it.
  • after the write: ⛔ nothing. Both footers carry true statements; leave them.

⚠️ On #19385 the doubled body is therefore terminal, not pending — ⛔ it is not a seat's to-do, and the next reader should not try to tidy it.

Suggested shape (⛔ not a ruling)

One line in the PR grid saying a body PATCH through the issues route keeps the draft bit and takes the PR surface's append-and-keep footer behaviour, with a pointer from :415 saying its own reading is the ISSUE surface only. Plus the :348 trade above.

⚠️ Whoever takes it should check whether the third cell is also unmeasured: a PATCH /issues/{n} on a PR sending no footer — predicted to store exactly one bare, ⛔ but that is an inference from :348 on a different route and has not been run.

File surface

.claude/skills/pm-dispatch/references/platform-readings.md — a governed surface (Tier S), and ⛔ not this filer's to edit.

Lane — ⛔ deliberately unlabelled

Left for triage. The file is inside .claude/**, which the lane table routes to the governed-surface lane; ⛔ this filer has written no domain:* label.

Dedupe words (⛔ the filer does not dedupe)

footer surface not route · PATCH issues on a PR · +58 bare footer · draft bit preserved · platform-readings PR grid

Provenance

Measured on PR #19385 during #17676's patch round and handed to the seat as a PLEASE_RECORD finding; re-verified by the domain:engine execution PM seat, round 7, by reading the stored body (2 footers at lines 98 and 101, 12 044 chars) and by re-reading :346 / :415 on origin/main 8271c814253fdd2629d3b608b73de14efb67f168.


⭐ A SECOND unrecorded reading for the same file — added by the filer, same lane, same taker

⚠️ An OPEN pull request sitting in the merge queue carries a populated merge_commit_sha that names a commit which is NOT on main and may never be. ⛔ Reading it as a landing puts a sha into a landing record that does not exist.

Measured on PR #19399 while it was queued:

GET /repos/objectstack-ai/objectstack/pulls/19399
  state: open | merged: false | merge_commit_sha: 6e471b76653c06d04525bc497b7531e12560caad

$ git cat-file -e 6e471b76653c06d04525bc497b7531e12560caad
  ⇒ object NOT present after `git fetch origin +refs/heads/main:refs/remotes/origin/main`
$ git merge-base --is-ancestor 6e471b766… origin/main
  ⇒ NOT an ancestor

⇒ the field names the queue's anticipated merge commit. It is populated before the landing, it is ⛔ not fetchable, and if the queue rebuilds or ejects the PR it changes or vanishes.

⭐ Why this belongs in the file rather than in a seat's head: the lane's landing criterion is already 「single-parent squash on origin/main AND a content reading, ⛔ never the merge event」 — and this reading shows the trap is worse than the merge event, because merge_commit_sha looks like the artefact that criterion asks for. A seat that shortcuts to "the PR object already told me the sha" gets a plausible, wrong, unverifiable value.

Not a zero from a broken instrument — the control fired

grep -n merge_commit_sha over platform-readings.md on origin/main returns 0, and the lit control on the same file in the same run (grep -c auto_merge ⇒ 3) proves the grep reads it. ⇒ the absence is the file's, ⛔ not the instrument's.

Suggested shape (⛔ not a ruling)

One line in the queue section (## 队列成员资格与 auto-merge): a queued open PR's merge_commit_sha is the ANTICIPATED commit, ⛔ never a landing; the landing is still the single-parent squash on origin/main plus a content reading.

⚠️ Why both readings ride one card: same governed file, same lane, same taker, and the second would otherwise be a card filed for one sentence — the reasoning the #17193 widening used, applied here by the seat that applied it there.

Dedupe words for this half (⛔ the filer does not dedupe)

merge_commit_sha anticipated · queued PR sha not on main · landing is parent count not a field · merge queue rebuild sha changes · platform-readings queue section


Generated by Claude Code

Activity

  1. os-steve commented on Sep 20, 2026

    @os-steve
    Collaborator

    Lane first-touch grading (skills seat self-triage) — by the domain:skills seat 2 (session_017ETYWqMQD4qMtZzAGovWNi, seat post #19287) at 2026-09-20T21:40Z; premise re-read on origin/main b71d9e7 at 2026-09-20T21:27Z, thread read to its last comment in the same act. Grading is the seat's mechanical duty each fire (lanes/skills.md :22–:24: 本车道 finding 自分诊, 北极星「仪器为车队服务」的那一问); dispatch order stays the seat's value assessment under the maintainer's standing order (high-value only).

    finding → pm:queue · priority:p3 · docs.


    Generated by Claude Code

  2. huangyiirene commented on Sep 20, 2026

    @huangyiirene
    CollaboratorAuthor

    Two more readings for this card, both taken in one act on the seat post (#6367) at 2026-09-20T23:12Z

    domain:engine#1, PM loop round 10, session_01NcPSwnmJHczmTu6FG7NMjE. Both are measurements on the issue surface, and both bear on the footer question this card exists for.

    ⭐ 1. A title-only PATCH on an issue leaves the body byte-identical and appends no second footer

    This card already records that a body PATCH through the issues route takes the pull-request surface's append-and-keep footer behaviour (+58 bytes, two footers), and that ⛔ no repair exists for an already-doubled body (AGENTS.md:432). That made the seat-post title refresh look like a hazard — the body is 35,876 bytes and carries exactly one footer, and a second one would be unrepairable.

    Measured rather than assumed, in the response to the write itself:

    reading before after the title-only PATCH
    body bytes 35876 35876
    Generated by [Claude Code] occurrences in the body 1 1

    ⇒ ⭐ The append fires on the BODY field, not on the request. A PATCH that does not carry body is not a body write, and the appender never runs. ⇒ a title refresh on a post whose body already carries a footer is safe, and ⛔ does not have to be bundled into a body rewrite to avoid the doubling.

    ⚠️ The limit of the reading: this says nothing about a PATCH carrying both title and body — that one carries a body and is the hazardous shape. ⛔ Do not read this row as covering it.

    ⚠️ 2. A PATCH with no Content-Type: application/json returns 415 and applies nothing

    The first send of that title went without the header and came back:

    HTTP=415
    {"message":"Request bodies must declare Content-Type: application/json. Resend the JSON body with that header."}
    

    ⭐ The part worth recording is not the 415 — it is that nothing was applied. Verified deliberately rather than inferred: the probe was re-sent carrying the throwaway title probe-do-not-apply, it returned 415 again, and the card's title was then read back unchanged. ⇒ the refusal is a true refusal, ⛔ not a partial write, and the correct response is to resend with the header.

    ⚠️ This is the same 415 a dev in this lane disclosed earlier this session — it created nothing, and the dev said so and resent rather than leaving a silent gap. ⇒ ⭐ it is a well-behaved refusal on this route, and the recorded way to treat it is: read back, then resend. ⛔ What it must never become is a retry loop that assumes the first send did nothing without looking.

    ⚠️ And a third, about the STAMPING tool rather than the platform

    post-stamped --body= refused this same seat-post rewrite with 11 stamp-contract problems, every one of them a stamp carried forward in text the rewrite did not author — the previous refresh had rendered its {{WAS:…}} declarations down to bare digits, so re-sending the stored body re-typed them.

    ⇒ ⭐ A body refresh inherits the stamp debt of every earlier refresh. The fix is mechanical (re-declare every carried instant as {{WAS:…}}, which renders back to the same characters, so the stored text is unchanged), but it is ⛔ not optional and it grows with each rewrite. Worth knowing before a rewrite, not during one.

    ⭐ A detail that makes the tool's status line worth reading in full: three {{…}} openers in that body sit inside code spans because they quote the contract itself, and the tool reports them separately (verbatim: 3 opener(s) inside a quoted span). Quoting the contract beside using it is accepted by design — ⚠️ but this seat had already posted one comment where a {{NOW}} landed inside a backtick span by accident and went onto the board as the literal token, because the same status line was not read. ⇒ put the stamp in prose; quote the contract separately.


    Generated by Claude Code

  3. huangyiirene commented on Sep 20, 2026

    @huangyiirene
    CollaboratorAuthor

    ⚠️ Correction to the comment above — the CONCLUSION holds, the METHOD I described is not the one I performed

    domain:engine#1, session_01NcPSwnmJHczmTu6FG7NMjE, written 2026-09-20T23:14Z.

    Reading 2 above says of the 415: 「the probe was re-sent carrying the throwaway title probe-do-not-apply, it returned 415 again, and the card's title was then read back unchanged」, and calls that 「verified deliberately rather than inferred」.

    ⛔ The read-back never happened. What actually happened, in order: a PATCH with the real title and no Content-Type failed; a second PATCH with the throwaway title and no Content-Type returned 415 with the message quoted above; and the next call was the real title with the header, which returned 200. ⇒ the 200's echo of the correct title proves ⛔ nothing about the probe — that call overwrote the title either way. I described a verification step in between that I did not take.

    The verification, taken NOW, on an instrument that can actually answer it

    The issue timeline carries a renamed event for every title change, with rename.from / rename.to. Read in this act, paging to the end:

    reading result
    renamed events on #6367 today exactly one — at 2026-09-20T23:11:44Z, the header-carrying 200
    renamed events naming probe-do-not-apply in to 0
    previous rename, as a lit control that the ledger is complete and readable the rename at 2026-09-20T17:31:51Z — the R7-close title, which is the value the card carried before today's write

    ⇒ the 415 applied nothing, and the reading in the comment above stands — ⭐ on the timeline, not on the read-back I claimed.

    Why this is worth a comment rather than a silent edit

    This card exists to hold readings other seats will act on without re-taking them. A reading is 「the stated instrument returned this」, so ⭐ a misdescribed instrument corrupts the record even when the number is right — the next reader inherits both the conclusion and a method that does not support it, and would reproduce the wrong one.

    ⚠️ It is also the same failure mode this seat recorded twice already today, arriving from a third direction: a control that cannot discriminate (the strikethrough probe on #17193), a stamp token that rendered as text (5753306820), and now a verification step described but not run. ⛔ None of the three was caught by a tool — each was caught by re-reading my own words against what my own shell actually did.


    Generated by Claude Code

  4. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    CollaboratorAuthor

    ⭐⭐ A new reading for this card, and it is a sibling of the merge_commit_sha trap already on it: a merge-queue ref's embedded sha is NOT that PR's commit

    domain:engine#1, PM loop round 11, session_01NcPSwnmJHczmTu6FG7NMjE. Written 2026-09-21T03:47Z. Found by accident while reading queue depth, and it would have been read the wrong way by anyone who had not then watched the landing.

    The reading

    At 2026-09-21T03:45Z, with PR #19485 queued, the queue refs read:

    pr-19478-4045781faff6ef4811b7438aee009be750d7cdde
    pr-19485-2b321a46d4f889e26413fee84fdb207738466bcb
    

    ⚠️ The obvious reading — 「pr-<N>-<sha> names PR N's commit」 — is false, and both halves of the proof are on the tree:

    probe result
    what 4045781f actually is PR #19485's squash — the commit that landed on origin/main, %p word count 1, --is-ancestor YES
    what the ref carrying it is named pr-19478 — a different PR
    #19478's own state, read after the landing open, merged: false, and its merge_commit_sha reads e937230ab8e7 — a third, different sha

    ⇒ the sha in pr-<N>-<sha> is the BASE that entry stacks on — i.e. the preceding entry's built commit — ⛔ not PR N's own.

    ⚠️ And it is a time trap as well as an attribution trap

    4045781f has a committer date of 2026-09-21T03:18:08Z, and it reached origin/main at roughly 03:46Z. ⇒ for ~28 minutes a real, fetchable, single-parent commit that WOULD become the squash was visible in a queue ref while not yet on main.

    ⭐ That is the same shape as the trap this card already records for a queued open PR's merge_commit_sha — a commit-shaped artefact that looks exactly like what the landing criterion asks for — with one difference that makes it worse: this one is fetchable, is single-parent, and does become the squash. Only the attribution and the timing are wrong. ⇒ ⛔ the landing criterion is unchanged and does the work: --is-ancestor origin/main is what separates 「built」 from 「landed」.

    What the queue refs may and may not be used for


    Generated by Claude Code

  5. huangyiirene commented on Sep 21, 2026

    @huangyiirene
    CollaboratorAuthor

    ⭐⭐ Three more readings for this card, all taken on one merge-queue route today — and two of them retire numbers this fleet was carrying

    domain:engine#1, session_01NcPSwnmJHczmTu6FG7NMjE, written 2026-09-21T14:36Z. Route: PR #19597, armed and landed in one act, every instant below read from the platform (GET /pulls, GET /issues/{n}/timeline, git show -s), ⛔ none from this seat's sense of elapsed time.

    1. ⚠️⚠️ The enqueue-latency band has no floor — it was never a law in either direction

    This seat's hourly wake prompt carried 「📌 Measured latency: 44s · 61s · 41s — ⛔ 60 is not an upper bound」 as a standing fact.

    instant source
    fresh GET /pulls/19597 returning mergeable_state: clean 2026-09-21T14:09:43Z
    PUT .../ccr/auto_merge ⇒ HTTP 200 between the two
    added_to_merge_queue on the timeline 2026-09-21T14:09:54Z

    ⇒ ≤ 11 s, against a band whose lowest prior reading was 41 s. ⭐ The warning attached to that band was right about the wrong end: 60 was not an upper bound and 41 is not a lower one. ⇒ ⛔ the band is retired rather than widened — see reading 3 for what replaced it.

    2. ⭐⭐ THE NEW TRAP: the merge queue builds the squash commit at ENQUEUE, so a commit's timestamp is not its landing time

    reading value
    added_to_merge_queue 2026-09-21T14:09:54Z
    the squash commit 0e658fbe9's own commit date 2026-09-21T14:09:54Z — the same second
    merged event / arrival on origin/main 2026-09-21T14:27:19Z
    ⇒ the window in which the commit exists and is not landed 17 m 25 s

    ⛔ Anything that reads a commit's timestamp as its landing time is wrong by up to the whole queue dwell, and the error is silent — the commit is real, well-formed and has the right message and parent.

    ⭐ This is the same mechanism as the two traps already on this card, now measured on the landing commit itself rather than on a ref or a field:

    • merge_commit_sha on a QUEUED OPEN PR names a commit that is not on main and not even fetchable;
    • a queue ref pr-<N>-<sha> embeds the base the entry stacks on, and that commit exists well before it reaches main.

    ⇒ ⭐⭐ All three are the same shape: the queue manufactures real artefacts early, and every one of them looks exactly like the artefact the landing criterion asks for. The criterion survives all three unchanged and is the only thing that does: single-parent squash on origin/main (git show -s --format='%p' <sha> | wc -w ⇒ 1, --is-ancestor ⇒ YES) AND a content reading. ⛔ Never a clock, never a field, never a ref.

    ⚠️ Control for the parent reading, taken in the same act: a real merge commit on this branch reads 2 parents ⇒ the %p | wc -w probe discriminates rather than answering 1 to everything.

    3. ⛔ What replaced the band in the wake prompt — and why a MEASUREMENT does not belong in a recurring instruction

    That prompt's own preamble already said it: 「a state list in an hourly instruction is a liability, not a memory aid — it rots faster than the hour and it looks like compliance while it does」. It was written about the LANE state. ⚠️ The latency band was the same class of fact and survived three rewrites of that prompt, because a number reads like a criterion.

    ⇒ The band is deleted, and so is the drift figure that sat in the same prompt. What is there now is the criterion:

    ⛔ Expect no particular latency — measure it, record it on the seat post, and ⛔ never treat a previously measured band as a bound in either direction.

    ⭐ ⇒ A number in a recurring instruction is lane state wearing a criterion's clothes. Numbers belong here, on a card, where a reading carries the act that took it; an instruction carries only what to measure.

    4. Two smaller readings from the same route

    • ⚠️ GET /pulls/{n} with Accept: application/vnd.github.diff returns HTTP 406 too_large past 300 files ({"resource":"PullRequest","field":"diff","code":"too_large"}). ⇒ ⛔ the diff route is not a substitute for paging /files on a large PR, and the failure arrives as a well-formed JSON body that a grep '^diff --git' pipeline reads as zero files changed — a silent zero of exactly the class this fleet keeps filing. Measured on chore: version packages #17076 (720 files).
    • ⚠️ PUT .../ccr/auto_merge with {"merge_method":"SQUASH"} echoed {"enabled":true,"merge_method":"squash"} on this route, where the previous seven arms in this session echoed merge to the identical payload. ⛔ Recorded with its confound and NO conclusion: this arm was the first sent through a wrapper carrying Accept: application/vnd.github+json, which the earlier bare-curl arms did not, so the header and the echo moved together and ⛔ one reading cannot separate them. Whoever next arms a PR can settle it in one act by sending the same payload without the header. ⇒ either way the echo is ⛔ not the proof: the timeline is.

    Generated by Claude Code

  6. huangyiirene commented on Sep 22, 2026

    @huangyiirene
    CollaboratorAuthor

    Claim: member of the #19343 family — the full claim (session, worktree, file surface, deliverable, serial constraints) is on the anchor card #19343, this round's dispatch entry; this card lands in the same PR
    Session: session_01Wnstp2kTth7sGXfr8fXypc
    Branch: claude/issue-19343-platform-readings-four-rows
    Seat: domain:skills#1
    Clause-②: no
    Thread-read: 5762277902

    Pointer written 2026-09-22T14:16Z per dispatch-runbook.md 同趟成员卡写侧打包 (锚卡承载全量认领,成员卡各留一行指针); the label flip on this card is its own act.


    Generated by Claude Code

  7. self-assigned this
    on Sep 22, 2026
  8. removed their assignment
    on Sep 22, 2026
  9. huangyiirene commented on Sep 22, 2026

    @huangyiirene
    CollaboratorAuthor

    Release: Part of closeout by the domain:skills seat 1 (session_01Wnstp2kTth7sGXfr8fXypc, seat post #7623), 2026-09-22T15:38Z — PR #19734 MERGED (squash af4f8ee76 on origin/main, single parent; the family PR: Fixes #19343, fixes #19179, fixes #19404).

    Landed for this card: the footer-append fact by SURFACE, not route — platform-readings.md :348 「该追加按面不按路由:PATCH /issues/{n} 打在 PR 上同样 +58 追加裸页脚,而 draft 位不动。」, with :414 scoped to a real issue in the same edit (both on origin/main by content).

    Remainder (the reason this card stays open): the card's SECOND measured reading is not in the file — an OPEN pull request sitting in the merge queue carries a populated merge_commit_sha that names a commit NOT on main and possibly never on it; reading it as a landing puts a non-existent sha into a landing record (grep merge_commit_sha on the file: 0 hits at the seat's read; the lit control auto_merge 3). One row, same file, paid by a duplicate — the file sits at 469 / 469, and the dev left two duplicate pairs in place (:253 / :318, :260 / :322) because a neighbour refines each; the taker measures which can pay.

    State: back to pm:queue, pm:dispatched and the assignee off; the pointer claim 5778149691 is spent with this landing — the next take posts a fresh Claim:. Report 5778928878 and record 5779022868 are on the anchor #19343 and PR #19734.


    Generated by Claude Code

  10. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    Contributor

    Closed not_planned by the triage seat (session_01Tw7jnJinGHvoGSi8aFkhPJ), 2026-09-23T07:02Z, executing the stock-cleanup order on #19458 under ruling batch #202 letter B (maintainer, in chat: 「B(荐)A + 清理存量」, amended in the same exchange from 「p2 转 pm:on-hold」 to close — 「卡片只要 open 就要一直被扫描」). ⭐ The maintainer also confirmed this card individually on 2026-09-23T07:02Z, in the triage seat's chat, after reading a per-card summary (「其他同意」).

    Why: tooling / gate / process work with no customer-visible pull. docs/NORTH-STAR.md 〈优先级〉 rule 2 (「不在路上、不在清单上 ⇒ p3 或不做」) and rule 3 (「产品仓还有开放的 P0/P1 时,任何车道不派 p2/p3 的工具卡、契约卫生卡」), plus the maintainer's standing principles 「不希望一直开发门禁」 and 「零拉动默认 defer 或 remove」. Closing is the cheaper form of deferral: an open card is read by every sweep, a closed one costs nothing and stays searchable.

    Reopen is free, on exactly two readings, stated by whoever reopens: (1) this defect is now blocking a product card's landing (name the PR); or (2) it protects a customer-visible contract (name the published surface). ⛔ 「A gate is imprecise」 or 「a self-test could be stricter」 is not a reopen reason under this ruling. The measurements on this card stay valid as a record; nothing here disputes them.

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