Repository navigation
perf(schema): validate each intent graph object once (ticket-109) - #140
Conversation
|
Correction to the 2.0× in the description. That came from one sample per side, taken while another heavy test suite was running, and wellmanifest/performance requires at least 3 comparable samples. I re-ran it with 3 interleaved pairs (ABABAB) on the same build, using
The median wall time drops from 384 s to 343 s, about 1.12×, but the spread is too large under this load to claim a precise figure. The output is identical in all 6 runs (base I'm now measuring user+sys CPU time, which load affects less, and will attach the evidence and a |
5cd60af to
44e0b72
Compare
|
Final measurement and fixes (commit
That is 1.41× less CPU; the per-pair ratios are 1.41, 1.24 and 1.40. Base and workspace fingerprints are identical across all 6 runs, and peak RSS is in the same range (2.9–3.5 GB).
This replaces both the earlier 2.0× claim and the wall-time comparison, which load made too noisy (see the previous comment). |
#135) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The |
44e0b72 to
b7ded18
Compare
There was a problem hiding this comment.
Validator approval after policy checks for exact head b7ded180c86d011c14b5ade399d886a51fb0f6d6.
Ticket: ticket-109
Correlation ID: todo2code-pr-140-ticket-109-b7ded180c8
Model: zai/glm-5.3
Reviewed diff chunks: 2
Advisory LLM verdict: APPROVE
Advisory summary: Reviewed all 2 diff chunk(s). Chunk 1 of 2 contains documentation, ticket metadata, intent, and performance evidence for the validate-once memoization change. All required checks (verify, Java adapter, koru/code-review, governance/enforce) pass. Performance evidence is internally consistent (median CPU 360.7s -> 255.3s, identical fingerprints across arms, failures never cached per invariants). No security concerns in this chunk; implementation code is in chunk 2 and reviewed there. | The diff adds a WeakMap-based memo to assertIntentGraph that skips repeat full validation when the graph object retains the same fingerprint string, identical records/relations array identities, and matching lengths. Failed validations are never cached (rememberValidatedGraph only runs at the end), and the new tests cover the memo hit, cache miss on cloned objects, mutated fingerprint rejection, and forced revalidation on array replacement. All required checks (verify, Java adapter, koru / code-review, governance / enforce) pass; SKIPPING outcomes are observational checks only and do not block.
Advisory findings: none
The LLM output above is advisory and was not used as the approval trust root.
Semantic review prerequisite: not_required; policy 676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7.
Actual PR impact radar
Exact range: a85da84e72c6c3fc7d2ea1c8b6eaf790f972a63f...b7ded180c86d011c14b5ade399d886a51fb0f6d6
Change digest: f716f006b289746b2e22627e9e9fb1b31c03c32b5b6eb721e2170e62b0ca7610
Score: 80/100 (L), estimated 155 min, split recommended: true
Affected services/components: repository-wide/unclassified
Machine-readable radar JSONL and SVG
{"actual_change":{"additions":491,"base_sha":"a85da84e72c6c3fc7d2ea1c8b6eaf790f972a63f","binary_files":0,"categories":{"code":1,"configuration":3,"docs":2,"tests":1},"change_digest":"f716f006b289746b2e22627e9e9fb1b31c03c32b5b6eb721e2170e62b0ca7610","comparison":"a85da84e72c6c3fc7d2ea1c8b6eaf790f972a63f...b7ded180c86d011c14b5ade399d886a51fb0f6d6","deletions":0,"file_count":7,"files":["project/TICKETS.md","project/ticket-109/README.md","project/ticket-109/evidence/validate-once-ab.json","project/ticket-109/intent.json","project/ticket-109/performance-plan.json","src/core/schema-intent-validation.ts","test/schema-validate-once.test.ts"],"head_sha":"b7ded180c86d011c14b5ade399d886a51fb0f6d6","service_count":0,"services":[]},"assessment_mode":"observed-pr","axes":{"coupling":5,"delivery":4,"scope":5,"uncertainty":3,"validation":3},"complexity":"L","confidence":0.9,"diagnostics":["RADAR-ACCEPTANCE-MISSING","RADAR-BUDGET-EXCEEDED"],"estimate":{"budget_minutes":30,"minutes":155,"within_budget":false},"impact":{"components":["A","claude.com","dist","origin","project","src/core","subactor","test"],"files":["A/B","claude.com/claude-code","dist/test/schema-validate-once.test.js","dist/test/schema-validation.test.js","dist/test/structured-schema.test.js","origin/main","project/TICKETS.md","project/governance-check.sh","project/ticket-109/README.md","project/ticket-109/evidence/validate-once-ab.json","project/ticket-109/intent.json","project/ticket-109/performance-plan.json","src/core/schema-intent-validation.ts","subactor/platform","test/schema-validate-once.test.ts"],"public_interfaces":["dist/test/schema-validate-once.test.js","dist/test/schema-validation.test.js","dist/test/structured-schema.test.js","src/core/schema-intent-validation.ts","test/schema-validate-once.test.ts"],"runtime_dependencies":1},"schema":"subactor.ticket-radar/v1","score":80,"split":{"parts":[{"estimated_minutes":20,"name":"Define contract and acceptance boundary","scope":["dist/test/schema-validate-once.test.js","dist/test/schema-validation.test.js","dist/test/structured-schema.test.js","src/core/schema-intent-validation.ts","test/schema-validate-once.test.ts"]},{"estimated_minutes":16,"name":"Implement A","scope":["A"]},{"estimated_minutes":16,"name":"Implement claude.com","scope":["claude.com"]},{"estimated_minutes":16,"name":"Implement dist","scope":["dist"]},{"estimated_minutes":16,"name":"Implement origin","scope":["origin"]},{"estimated_minutes":16,"name":"Implement project","scope":["project"]},{"estimated_minutes":15,"name":"Validate and project to trackers","scope":["tests","planfile","github/gitlab/jira projections"]}],"reason":"estimated_minutes_exceed_budget","recommended":true},"standards":[{"id":"wellmanifest/dsl","revision":"6c60fc4e0dd1f1bb74f46a7745e28019908d1203","version":"0.1.0-dev"},{"id":"wellmanifest/ticket-lifecycle","revision":"5bf581907a87b46a13a73e6c033d3abe4d9a306f","version":"0.1.0-dev"},{"id":"wellmanifest/git-lifecycle","revision":"7d77d4b7af57e69bc75c3a0290b3a4805c5c4438","version":"0.2.0-dev"},{"id":"wellmanifest/logs","revision":"48c284ef7a069055c0bcb6b900147ce5e65f8b43","version":"0.3.0"}],"ticket_ref":"ticket-109"}<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img"><title>ticket-109: perf(schema): validate each intent graph object once (ticket-109)</title><rect width="128" height="128" rx="12" fill="#f8fafc"/><g stroke-width="1"><polygon points="64,55 72,61 69,71 59,71 56,61" fill="none" stroke="#d7dde5"/><polygon points="64,47 80,59 74,78 54,78 48,59" fill="none" stroke="#d7dde5"/><polygon points="64,38 89,56 79,85 49,85 39,56" fill="none" stroke="#d7dde5"/><polygon points="64,30 97,53 84,92 44,92 31,53" fill="none" stroke="#d7dde5"/><polygon points="64,21 105,51 89,99 39,99 23,51" fill="none" stroke="#d7dde5"/><line x1="64" y1="64" x2="64" y2="21" stroke="#aab4c0"/><line x1="64" y1="64" x2="105" y2="51" stroke="#aab4c0"/><line x1="64" y1="64" x2="89" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="39" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="23" y2="51" stroke="#aab4c0"/></g><polygon points="64,21 105,51 79,85 49,85 31,53" fill="#fb923c" fill-opacity="0.45" stroke="#c2410c" stroke-width="2"/><circle cx="64" cy="64" r="3" fill="#c2410c"/><g font-family="sans-serif" font-size="7" fill="#334155"><text x="64" y="11" text-anchor="middle">SCO</text><text x="114" y="48" text-anchor="middle">COU</text><text x="95" y="107" text-anchor="middle">UNC</text><text x="33" y="107" text-anchor="middle">VAL</text><text x="14" y="48" text-anchor="middle">DEL</text></g><text x="64" y="124" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#0f172a">L · 155m</text></svg>DECISION D-109-9992
TICKET ticket-109
HEAD_SHA b7ded180c86d011c14b5ade399d886a51fb0f6d6
CORRELATION_ID todo2code-pr-140-ticket-109-b7ded180c8
ACTOR agent:ifuri-validator-agent[bot]
APPLIED_RULE P-CORE-015
INPUT author_login = "tom-sapletta-com"
INPUT observed_checks = ["Live OpenRouter contract (opt-in)=SKIPPING","governance=SKIPPING","verify=PASS","Java adapter (JDK 17 required)=PASS","governance / remote lifecycle=PASS","koru / code-review=PASS","governance / enforce=PASS","verify=PASS","Java adapter (JDK 17 required)=PASS"]
INPUT required_checks = ["verify","Java adapter (JDK 17 required)","koru / code-review","governance / enforce","governance / governance / enforce"]
INPUT required_checks_source = "protected registry + GitHub applied rules (env/request)"
INPUT reviewer_login = "ifuri-validator-agent[bot]"
INPUT semantic_review_assessment = {"schema":"subactor.validator/semantic-review-assessment/v1","subject":{"repository":"autogrammar/todo2code","pull_request":140,"head_sha":"b7ded180c86d011c14b5ade399d886a51fb0f6d6","base_sha":"a85da84e72c6c3fc7d2ea1c8b6eaf790f972a63f","diff_sha256":"5b8dbc9b1b2eb17b8cf03c5545c9a41b4e23a56bae9fef1a05e48da1a7eb31bc"},"policy":{"policy_schema":"subactor.validator/semantic-review-policy/v1","policy_version":1,"policy_sha256":"676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7","required":false,"critical_paths":[],"observed_paths":["project/TICKETS.md","project/ticket-109/README.md","project/ticket-109/evidence/validate-once-ab.json","project/ticket-109/intent.json","project/ticket-109/performance-plan.json","src/core/schema-intent-validation.ts","test/schema-validate-once.test.ts"]},"grounding":"full-diff-not-per-finding-proof","execution_authority":false,"status":"not_required","reason":null,"review_sha256":null,"unresolved":[]}
INPUT superseded_checks = []
INPUT ticket_radar_receipt = {"schema":"subactor.ticket-radar/v1","base_sha":"a85da84e72c6c3fc7d2ea1c8b6eaf790f972a63f","head_sha":"b7ded180c86d011c14b5ade399d886a51fb0f6d6","change_digest":"f716f006b289746b2e22627e9e9fb1b31c03c32b5b6eb721e2170e62b0ca7610","score":80,"complexity":"L","estimated_minutes":155,"split_recommended":true,"services":[],"authority":"ADVISORY","promotion":"FORBIDDEN"}
VERDICT APPROVE AUTHORITY DETERMINISTIC
REJECTED REQUEST_CHANGES BECAUSE NO_UNSAFE_CHANGE_REASON_FOUND
ADVISORY llm_verdict = "APPROVE" MODEL "zai/glm-5.3"
ASSERT VERDICT_AUTHORITY != "ADVISORY"
Closes #135.
assertIntentGraphused to re-validate the same graph object about 9 times per pipeline and recompute its canonical-JSON fingerprint each time. AWeakMapmemo now skips a repeated full validation when the object still has:fingerprintstring;records/relationsarray identities and lengths.Failed validations are never cached, and a revert restores the old behaviour.
Measured (superseded: see the final comment, where 3 interleaved CPU-time pairs give 360.7 → 255.3 s, 1.41×) on the same build,
compare-workspaceon subactor/platform (50k records / 415k relations):T2C_REVALIDATE_GRAPHS=1(old behaviour)The base and workspace fingerprints,
trendanddiff.summaryare identical in both runs. The absolute times are inflated because another test suite was running on the machine at the same time; the A/B ratio is the meaningful figure.Review note. Willman drafted the patch via koru.develop_ticket (glm-5.3) from an exact spec, and it passed review unchanged.
Verification:
npm run build && T2C_USE_SUBLLM=false node --test dist/test/schema-validate-once.test.js dist/test/schema-validation.test.js dist/test/structured-schema.test.js→ 10 pass../project/governance-check.sh --base origin/main→ GOV-PASS.Follow-ups: #136 (cache the base pipeline), #137 / #139 (exposed diagnostics), #138 (Rust kernel RFC).
🤖 Generated with Claude Code