Skip to content

feat(proof): name the topic_id / custom_id hyphen-underscore mix-up (Architecte follow-up 4/4) - #251

Merged
echobt merged 2 commits into
mainfrom
cursor/proof-topic-custom-id-slug-hints
Sep 9, 2026
Merged

feat(proof): name the topic_id / custom_id hyphen-underscore mix-up (Architecte follow-up 4/4)#251
echobt merged 2 commits into
mainfrom
cursor/proof-topic-custom-id-slug-hints

Conversation

@echobt

@echobt echobt commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Architecte / Owner follow-up 4 of 4 (topic_id ↔ custom_id slug alignment). Based on main; independent of the other three.

The mix-up. Topic ids are hyphen slugs ([a-z0-9][a-z0-9-]{1,62}); metric.custom_id, checklist ids and PROOF_VM_RUNNER_CUSTOM_IDS are identifiers that may carry underscores ([a-z0-9][a-z0-9_-]{1,63}), and the runner is looked up by custom_id byte-for-byte. Staging used staging-fc-colo-test for the topic and staging_fc_colo_test for the metric, and every rejection just printed the regex.

Decision: keep both rules, document the canonical mapping, make every message explain it. Loosening the topic slug would touch a URL path segment, the VM / jail / nftables names, and the DB CHECK (topic_id ~ '^[a-z0-9][a-z0-9-]{1,62}$') in 0020_proof_rlm.sql; tightening custom ids would break signed topics and rule ids that already use _. Neither is worth it for a UX problem, so the UX is fixed instead:

  • proof-canon: slug_hint / custom_id_hint (why it is malformed — "topic ids are slugs with hyphens only — underscores belong to metric.custom_id / checklist ids", "lower-case only", "no whitespace" — plus a corrected form: did you mean "staging-fc-colo-test"?), id_twin (the registered id that equals this one up to _- / case), twin_suffix. Namespace doc on is_slug / is_custom_id.
  • proof-task: TopicError::BadId carries the hint; new TopicError::BadCustomId { id, hint } names metric.custom_id (was a generic BadBinding); UnknownCustomMetric { id, twin } names the registered twin: custom metric "staging_fc_colo_test" has no registered runner on this host; a topic may draft but not open (ids match byte-for-byte: "staging-fc-colo-test" is registered, and '_' is not '-'; use exactly that id in metric.custom_id / PROOF_VM_RUNNER_CUSTOM_IDS).
  • proof-rlm: RunnerError::Unregistered { custom_id, twin } — the 503 miners and operators see carries the same twin sentence; RunnerError::BadCustomId (what PROOF_VM_RUNNER_CUSTOM_IDS: … skipped logs at boot) carries the hint and corrected form.
  • Wire check: env explains byte-for-byte matching and that the topic id never looks a runner up; boot-probe suggests the slug form for a bad --probe-topic.
  • Runbook § Identifiers: the mapping table (which id, which shape, where used, example), the canonical rule (runner ← metric.custom_id exactly; convention custom_id = slug with -_ is a habit, not something code derives), and a "you did / you see" table of the new messages. docs/PROOF.md field table and the staging env example say the same.

Behaviour is unchanged for every well-formed input: same accept / reject decisions, same status codes; only error texts and two error-variant shapes (matched with { .. } at the 3 sites) changed.

How to verify

cargo test -p proof-canon -p proof-task -p proof-rlm -p proof-rlm-scorer -p proof-http -p proof-challenge-bin

Messages to expect (also in the runbook table):

You did You see
topic id: "staging_fc_colo_test" topic id "staging_fc_colo_test" must match [a-z0-9][a-z0-9-]{1,62}; topic ids are slugs with hyphens only — underscores belong to metric.custom_id / checklist ids …; did you mean "staging-fc-colo-test"?
metric.custom_id: "Staging FC" topic binding metric.custom_id "Staging FC" must match [a-z0-9][a-z0-9_-]{1,63}; lower-case only; no whitespace; did you mean "staging_fc"?
topic opens with custom_id: staging_fc_colo_test, host registered staging-fc-colo-test … has no registered runner … (ids match byte-for-byte: "staging-fc-colo-test" is registered, and '_' is not '-'; …) — at publish (400) and at submit (503, no row)
PROOF_VM_RUNNER_CUSTOM_IDS=Staging-FC boot log custom id "Staging-FC" must match …; lower-case only; did you mean "staging-fc"?; skipped

Greptile

  • Greptile has reviewed this PR; findings are fixed or answered
  • If the bot was silent, I commented @greptileai review

Test plan

  • cargo test --workspace (isolated target dir)
  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings, cargo deny check, xtask loc-cap (proof-task 1490 / 1500) / consensus-lint / spec-check / design-check / external-docs-check

Risk

None to deploy, measurement, signature domains, or emission: no id rule changes, no schema change, no wire change. Error strings are longer; anything matching them by prefix (custom metric … has no registered runner, topic id … must match …) still matches.

Naming

I did not rename BASE_* environment variables, deployed host paths
(/opt/base, /run/base, …), GHCR baseintelligence/base package names, or
base-*-v1 cryptographic domain tags, unless this PR’s purpose is a coordinated
cutover documented in docs/NAMING.md.

Open in Web Open in Cursor 

cursoragent and others added 2 commits September 9, 2026 00:20
Topic ids are hyphen slugs ([a-z0-9-]); metric.custom_id, checklist ids and
PROOF_VM_RUNNER_CUSTOM_IDS are identifiers that may carry underscores, and
the runner is looked up by custom_id byte-for-byte. Staging typed one for
the other (staging-fc-colo-test vs staging_fc_colo_test) and the messages
did not say why. Rules stay as they are (the topic slug is a URL segment, a
jail name and a DB CHECK); the UX now explains: TopicError::BadId and
RunnerError::BadCustomId carry the namespace hint and a corrected form
("did you mean ..."), a new TopicError::BadCustomId names metric.custom_id,
and UnknownCustomMetric / RunnerError::Unregistered name the registered
'_'/'-' twin when there is one (proof_canon::{slug_hint, custom_id_hint,
id_twin}). Wire-check messages and env comments say the same; the runbook
gains an Identifiers section with the canonical mapping table.
@echobt

echobt commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@greptileai please review topic_id/custom_id slug hints (Architecte follow-up 4/4) after rebase onto main post-#252.

@greptile-apps

greptile-apps Bot commented Sep 9, 2026

Copy link
Copy Markdown

Greptile Summary

This PR improves diagnostics and operator documentation for the distinct Proof identifier namespaces without changing identifier validation or lookup behavior. It explains topic IDs versus custom metric IDs, provides corrected identifier guidance, and propagates clearer failures through publication, runner resolution, scoring, deployment checks, and operator runbooks.

Confidence Score: 5/5

Safe to merge; there are no outstanding blocking issues.

The previously reported retry-suggestion issue was manually resolved without explanation by echobt. It is not outstanding.

Reviews (2): Last reviewed commit: "Merge branch 'main' into cursor/proof-to..." | Re-trigger Greptile

Comment thread deploy/scripts/proof-vm-wire-check.sh
@echobt
echobt marked this pull request as ready for review September 9, 2026 01:28
@echobt
echobt merged commit 85ab2b7 into main Sep 9, 2026
5 checks passed
@echobt
echobt deleted the cursor/proof-topic-custom-id-slug-hints branch September 9, 2026 01:28
cursor Bot pushed a commit that referenced this pull request Sep 9, 2026
Retarget #245: main moved to #251. Digests from images run
34299348722. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Sep 9, 2026
Retarget #245: main moved to #251. Digests from images run
34299348722. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
cursor Bot pushed a commit that referenced this pull request Sep 9, 2026
Retarget #245: main moved to #251. Digests from images run
34299348722. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>
echobt added a commit that referenced this pull request Sep 9, 2026
* deploy: staging pins for 4252130

images.yml built GHCR digests on main then could not push the pin
commit (GH013: PRs required + Greptile). Land the same promote via PR.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* fix(deploy): keep full prior staging release in previous

Sequential promote.sh calls were snapshotting previous per service,
so rollback of 4252130 would restore a mixed pin set. Capture the
1dd07f7 release once and write it back after the promote loop.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for f013abb

Retarget #245: main moved to #246. Digests from images run
34281980177. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for 890ce5b

Retarget #245: main moved to #247. Digests from images run
34286333214. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for c0ce094

Retarget #245: main moved through #248/#252. Digests from images
run 34297422117. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for 85ab2b7

Retarget #245: main moved to #251. Digests from images run
34299348722. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for e30d51d

Retarget #245: main moved to #250. Digests from images run
34302039784. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

* deploy: staging pins for a8b9018

Retarget #245: main moved to #253. Digests from images run
34373475123. previous stays the full 1dd07f7 staging release.

Co-authored-by: Mathis <echobt@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Mathis <echobt@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants