Repository navigation
§06 F14 says an archived contract stays editable 「除 notes 外」, but clm_contract has no notes field — §03 gives it summary #44
Description
Activity
- added a commit that references this issue
on Sep 10, 2026 zhuangjianguo commented
on Sep 10, 2026 CollaboratorAuthorMore actionsClaim: session
session_01R3n3GGzobdegM4HUzah1iR· branchclaude/issue-44-design-summary-not-notesPM dispatch. The assignee and this claim are set by the PM seat on behalf of the dev that will work this card; the dev inherits both, checks that this is the newest
Claim:on the thread and that it names its branch, and ⛔ posts no second claim and never writes the assignee field.Unblocked. PR #40 merged at 10:48Z as
296fab8— the maintainer's merge, on the governed path, exactly asAGENTS.mdrequires.DESIGN.mdis unheld. Branch off currentorigin/main(296fab8).⚠️ Re-read §06 F14 on296fab8before editing. PR #40 just changedDESIGN.md§02, §03, §06 and §09 — including a §06 edit (F9 lost its intake-payment clause). Your target sentence is a different F, but the file moved under this card and the card was written against the pre-#40 text. Confirm 「此后除 notes 外只读」 is still there, verbatim, and confirm §03 still givesclm_contractasummaryand nonotes. If either moved, stop and say so.Dispatch notes on top of the card body:
- One word. 「除 notes 外只读」 → 「除 summary 外只读」. ⛔ Nothing else in §06, ⛔ nothing in any other section.
- §06 is outside the governed range (
AGENTS.mdgovernsDESIGN.md§01–§04), so this merges on the normal path. ⛔ Do not touch §01–§04 — a single character there converts this one-word fix into a human-merge PR. - Two more
DESIGN.mdcards are queued behind you — docs: the position census disagrees with itself in three places — README says seven over a table of six, DESIGN.md §11 says both 7 and 8 #58 (§11) andDESIGN.md§09 still specifies 各阶段合同数**漏斗** — the app stopped shipping a funnel in #48 and narrowed what it plots in #59 #63 (§09). They are NOT dispatched and will not be until yours merges. ⛔ Do not fold either in, and ⛔ do not "while I'm here" any other §06 sentence. - Gates all four, exit codes captured before any pipe. None of them reads
DESIGN.md(tsconfigincludes onlyobjectstack.config.tsandsrc/**/*; validate/lint walk the metadata graph) — say that plainly rather than implying they verified the change. No changeset (this repo has no changeset gate — do not add one). No browser run: the diff changes no runnable surface. - The evidence this card wants is not a gate run. It is the reading that
summaryis the field F14's freeze actually leaves open. The card citescontract.hook.tsand a measured422 Fields refused: title/200onsummary; confirm that against the tree you branch from rather than inheriting it, and put the reading in the PR body.
Generated by Claude Code
zhuangjianguo commented
on Sep 10, 2026 CollaboratorAuthorMore actionsACCEPT — PR #68
CI green on head
1187094b(twoValidateruns, both success), base is currentmain(296fab8), diff isDESIGN.mdline 239, +1/−1, and §06 is outside the governed range (AGENTS.mdgoverns §01–§04). First round. Squash-merging.The premise re-check earned its place
I asked for it because PR #40 had merged minutes earlier and moved §02/§03/§06/§09. You re-read both premises on
296fab8and reported something the card got slightly wrong:The file spells it 「此后除
notes外只读」 —notesin backticks; the card quoted it with the code formatting dropped.That is the right level of care for an exact-match edit. A card that quotes a target string without its formatting is one
sedaway from a no-op that reports success.The reading, not the gates
This card's whole content is a claim about which field the freeze leaves open, and you answered it from the source rather than from the card's inherited measurements:
OPEN_AFTER_ARCHIVE = ['summary', 'id', 'organization_id', 'created_at', 'created_by', 'updated_at', 'updated_by']with the observation that makes it decisive —
summaryis the only caller-authorable name in that list; the other six are the id, the tenant column and the engine's audit columns that ride along on every write. From which the card's "taking §06 literally would freeze the contract completely" stops being rhetoric: the allow-list is keyed by field name, anotesentry matches nothing onclm_contract, and the remainder is zero writable fields.Turning "say it plainly" into a measurement
The dispatch told you to state that no gate reads
DESIGN.mdrather than implying the gates verified this. You did — and then you proved it:Mechanically:
grep -il DESIGNacross all four gate logs → no match.That is better than the instruction. The
tsconfig-include argument establishes it should be true; the grep establishes it is true of the four logs actually attached to this PR. On a repository where three of this session's ten merges touched files no gate can see, having the negative demonstrated rather than argued is worth the two seconds it cost.The stale comment — your call ratified, and recorded so it is not lost
src/objects/contract.hook.tsquotes the pre-fix sentence verbatim as the premise for its allow-list, and after this merges that quote reads as history. You left it alone and said why. Agreed, and it is not being filed — recording the reasoning here rather than in a card so the decision is on GitHub either way:The comment is not false. It accurately records what §06 said when the hook was written, why the implementation diverged, and its closing line — "Reported as a §06/§03 wording mismatch rather than resolved by adding a field: §03 is a governed surface" — is a report that this PR closes out. Deleting a correct historical note would be churn, and touching
src/to do it would widen a one-word §06 diff into the gated surface. It is a free rider for whoever next opens that file for a real reason; neither #58 nor #63 does.Queue
#58 (§11) dispatched next, alone. #63 (§09) after it. ⛔ Still one
DESIGN.mdcard at a time.
Generated by Claude Code
zhuangjianguo commented
on Sep 10, 2026 CollaboratorAuthorMore actionsos-dev-report
{ "issue": 44, "status": "done", "branch": "claude/issue-44-design-summary-not-notes", "pr": "https://github.com/objectstack-ai/hotclm/pull/68", "premise_still_valid": true, "summary": "One word in DESIGN.md §06 F14: 「此后除 `notes` 外只读」 → 「此后除 `summary` 外只读」, at DESIGN.md:239. Whole diff is 1 file, 1 insertion, 1 deletion; §01–§04 untouched, no other §06 sentence touched, neither queued DESIGN.md card (#58, #63) folded in. Both premises were re-read on 296fab8 after PR #40 moved §02/§03/§06/§09 and both hold: the F14 sentence is present and unmoved (the file spells `notes` in backticks; the card quoted it with the code formatting dropped — same sentence), and §03 still gives clm_contract `summary` with zero `notes`. The assignee was already set and the newest Claim: comment already names this session and branch, so I inherited both and posted no second claim and never wrote the assignee.", "tests": "GATES (all four run in the dedicated worktree, each redirected to its own file with $? read on the very next statement — no pipe between command and exit code): pnpm validate=0 ('✓ Validation passed (2275ms)'), pnpm lint=0 ('21 warning(s), 5 suggestion(s) (1367ms)'), pnpm typecheck=0 (tsc --noEmit, no diagnostics), pnpm lint:i18n-gate=0 ('✓ i18n gate' · 'COVERAGE : 0 missing keys across 2 locale(s)'). NOT EVIDENCE FOR THIS CHANGE, stated plainly: none of the four reads DESIGN.md — tsconfig.json include is [\"objectstack.config.ts\",\"src/**/*\"] so the file is not in the typecheck program, validate/lint walk the compiled metadata graph from objectstack.config.ts, and `grep -il DESIGN` across all four gate logs returns no match. They are recorded only because AGENTS.md requires them green before a PR opens, and they show the branch did not disturb the metadata graph. The validate/lint warnings are pre-existing on 296fab8 (carrier-only field notices, one approval-routing suggestion), none on clm_contract.summary or the archive path. THE ACTUAL EVIDENCE is the reading, confirmed against 296fab8 rather than inherited from the card, and tabulated in the PR body: contract.object.ts:366 declares `summary: Field.richtext(…)` and grep -c notes on that file returns 0; contract.hook.ts hook `contract_archive` has OPEN_AFTER_ARCHIVE = ['summary','id','organization_id','created_at','created_by','updated_at','updated_by'], in which `summary` is the only caller-authorable name (the other six are the id, the tenant column and the engine audit columns that ride along on every write); the gainsArchiveNo && !terminal branch throws refuse(…, 'INVALID_STATE', 422) interpolating the status, which is the card's 422 on an `active` contract; the terminal side sets input.archived_at = new Date().toISOString(), which is the 200 with archived_at stamped; `summary` in the allow-list leaves `attempted` empty, which is the 200 on a summary edit; `title` absent from it lands in `attempted` and yields exactly 'Fields refused: title', which is the card's 422. Rows 4-7 are readings of the code path that produces each measured response, not a fresh HTTP re-measurement — no browser run is owed since the diff changes no runnable surface. ON-DISK PROOF of the edit itself (the docs-only analogue of an ablation; no ablation or reverse-verification applies because no code changed and nothing new can fail): before the sed, old-spelling count = 1 and new-spelling count = 0; after, old = 0 and new = 1; git diff shows exactly the one line at DESIGN.md:239. Control-character self-scan on the edited file and on the PR body: grep -naP '[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f\\x7f]' → no match on either. NO CHANGESET: this repo has no changeset gate and no .changeset/ convention; release notes are written centrally at release time. NO VERIFY LOCK: scripts/pm/os-verify-lock.sh does not exist in hotclm (it is an objectstack-repo mechanism), so the gates were run directly.", "mcp_calls": "5 — issue_read get, issue_read get_comments, create_pull_request, pull_request_read get, add_issue_comment (this report). No search call was needed: the card names its own target and no duplicate check was owed, since nothing was filed.", "open_questions": [], "out_of_scope_findings": [ "noted, not filed: src/objects/contract.hook.ts quotes the pre-fix §06 sentence verbatim in a comment (「\"此后除 notes 外只读\" (§06 F14)」) as the premise for its allow-list; once this merges the quote reads as history rather than as the current text. Stale phrasing, not a defect — no runtime behaviour, gate or contract depends on it, and the reasoning it records is exactly what this PR codifies. Left alone deliberately: the card is one word in §06 and touching src/ would widen a docs diff into the gated surface for a comment. Successor: none — the two DESIGN.md cards queued behind this one (#58 on §11, #63 on §09) do not touch contract.hook.ts.", "noted, not filed: the MCP create_pull_request path appended its own '_Generated by [Claude Code](https://claude.ai/code/session_…)_' footer after the one already in the body I sent, so PR #68 carries two attribution footers. Left as-is rather than looped on — editing the body to drop one risks the same append again. Platform/tooling behaviour, reported not patched." ] }
Generated by Claude Code
- added a commit that references this issue
on Sep 10, 2026
Documentation drift, found while browser-verifying card 09 (#39 / PR #42, merged as
a7b7db5). The implementation is not wrong; the sentence is. ⛔ Not a decision card — there is nothing to choose.The mismatch
DESIGN.md§06 F14 says that after archiving, a contract is 「此后除 notes 外只读」 — read-only exceptnotes.DESIGN.md§03 givesclm_contractasummaryfield and putsnoteson the child objects (clm_contract_version.notes,clm_obligation.notes,clm_signature.notes). There is nonoteson the contract, and there never was.What the implementation did, and why it is right
contract.hook.ts's F14 freeze keepssummaryopen (plus the platform'supdated_at/updated_by, which ride along on every write). That is the only reading that leaves an archived record annotatable at all — the alternative, taking §06 literally, would freeze the contract completely, because the field it names to keep open does not exist.Measured on the merged branch:
archive_noon anactivecontract → 422 naming the status; on aterminatedone → 200 witharchived_atstamped; then editingsummary→ 200, editingtitle→ 422 Fields refused: title`.Fix
One word in §06 F14: 「除 notes 外只读」 → 「除 summary 外只读」.
AGENTS.mdgovernsDESIGN.md§01–§04 only), so a §06-only edit self-merges on the normal path. ⛔ Do not fold it into a PR that also touches §01–§04, or it inherits the human-merge path for one word.⛔ Also do not fold this into PR #40 (chain head #6): that PR is already reviewed, ACCEPTed and awaiting the maintainer's merge. Adding a commit would invalidate a review that is already on the record.
Related
#39 / PR #42 (found here) ·
src/objects/contract.hook.tsF14 ·DESIGN.md§03 field list, §06 F14