gabriel / muse public
feat patch task/sign-propose #1 / 1
AI Agent gabriel · 127 days ago · May 8, 2026 · Diff

feat: muse sign propose — Ed25519 signing for merge proposal pre-images

New subcommand: muse sign propose --repo-id sha256:<hex> --from-branch <name> --to-branch <name> --hub <url> --json

Outputs proposerPublicKey, proposerSignature, and proposerTimestamp ready to pass directly to muse hub proposal create or the MuseHub REST API.

Also exports canonical_propose_message() — the deterministic UTF-8 byte builder that both the CLI and the MuseHub server use to construct and verify the PROPOSE pre-image. Uses encode_sig/encode_pubkey from muse.core.types throughout — no manual prefix manipulation.

11 TDD tests covering: canonical message format, determinism, proposal_id presence/absence, signature verification, JSON/human-readable output, argparse registration.

sha256:a2e2226b0b27c3a123da1b746ea1c8c4b7a4ad632d763e7b6da35e0dfbcc8fc8 sha
+42 ~5 symbols
sha256:8ac3e117d96a4d875e56357b328c78312bcfe81e492ed28ad0adb5053d9c80e4 snapshot
+42
symbols added
~5
symbols modified
0
dead code introduced
Semantic Changes 47 symbols
~ tests/test_cmd_sign_propose.py .py 35 symbols added
+ TestCanonicalProposeMessage class class TestCanonicalProposeMessage L81–148
+ _import method method _import L82–84
+ test_deterministic method method test_deterministic L86–97
+ test_format_contains_all_fields method method test_format_contains_all_fields L133–148
+ test_with_proposal_id method method test_with_proposal_id L115–131
+ test_without_proposal_id method method test_without_proposal_id L99–113
+ TestRegistration class class TestRegistration L230–246
+ test_propose_subcommand_registered method method test_propose_subcommand_registered L231–246
+ TestRunPropose class class TestRunPropose L155–223
+ _run method method _run L159–166
+ setUp method method setUp L156–157
+ test_human_readable_output method method test_human_readable_output L198–208
+ test_json_fields_present method method test_json_fields_present L168–175
+ test_passthrough_fields method method test_passthrough_fields L216–223
+ test_public_key_matches_signing_identity method method test_public_key_matches_signing_identity L177–185
+ test_signature_verifies method method test_signature_verifies L187–196
+ test_timestamp_used_in_message method method test_timestamp_used_in_message L210–214
+ _base_args function function _base_args L63–74
+ _make_signing function function _make_signing L57–60
+ Ed25519PublicKey import import Ed25519PublicKey L46–46
+ StringIO import import StringIO L42–42
+ TYPE_CHECKING import import TYPE_CHECKING L43–43
+ annotations import import annotations L34–34
+ argparse import import argparse L36–36
+ b64url_decode import import b64url_decode L47–47
+ b64url_encode import import b64url_encode L47–47
+ datetime import import datetime L41–41
+ decode_pubkey import import decode_pubkey L47–47
+ decode_sig import import decode_sig L47–47
+ json import import json L37–37
+ patch import import patch L44–44
+ sys import import sys L38–38
+ timezone import import timezone L41–41
+ unittest import import unittest L39–39
+ mock import import unittest.mock L40–40
~ muse/cli/commands/sign.py .py 7 symbols added, 5 symbols modified
+ _SignProposeJson class class _SignProposeJson L566–578
+ canonical_propose_message function function canonical_propose_message L528–563
+ datetime import import datetime L84–84
+ encode_pubkey import import encode_pubkey L85–85
+ encode_sig import import encode_sig L85–85
+ timezone import import timezone L84–84
+ run_propose function function run_propose L581–669
← Older Oldest on task/sign-propose
All commits
Newer → Latest on task/sign-propose

0 comments

No comments yet. Be the first to start the discussion.

To add a comment, use the Muse CLI: muse hub commit comment sha256:a2e2226b0b27c3a123da1b746ea1c8c4b7a4ad632d763e7b6da35e0dfbcc8fc8 --body "your comment"