Open
feat(#215,#216): tip created_by author fallback + BranchMeta creation provenance
Summary
Implements musehub issues #215 and #216 on gabriel/muse.
- #215 —
muse branch --jsoncreated_byfalls back from tipagent_idto human.author(no longer null for human tips). - #216 — write-once BranchMeta
created_by/created_by_kind/created_atstamped at branch create sites; additive list JSONbranch_created_by+branch_created_at. Tipcreated_bymeaning unchanged (#215).
Tip
sha256:5eff0848db1d0748f3a195ca871a9275e7455d447690411ec2d83434e11baa65
Issues
- https://staging.musehub.ai/gabriel/musehub/issues/215
- https://staging.musehub.ai/gabriel/musehub/issues/216
Notes
Local-only BranchMeta (no push/clone/wire changes). Freezes + BV pass on the feature branch. Please review → merge to dev.
high
risk
minor
semver
0/2
approvals
merge
type
Symbol Delta
156 symbols
111 added
34 modified
11 deleted
docs/MUSE-216-BRANCHMETA-CREATED-BY-FREEZE.md
30
+
FREEZE — musehub#216 BranchMeta createdby/createdat provenance (Thinking).3. Fail-closed rules.table
+
FREEZE — musehub#216 BranchMeta createdby/createdat provenance (Thinking).5. Seven-tier test matrix
docs/MUSE-OVERSEER-HANDOVER.md
32
docs/MUSE-ROADMAP.md
6
muse/cli/commands/branch.py
14
~
run
muse/cli/commands/checkout.py
3
muse/cli/commands/switch.py
2
muse/cli/commands/worktree.py
2
muse/cli/config.py
14
tests/test_branch_intent_created_by.py
3
tests/test_branch_json_schema.py
1
Files Changed
287 of 1,169
A
.claude/skills/build-verification-review/SKILL.md
A
.claude/skills/check-ok/SIDE-CHECK-TEMPLATE.md
A
.claude/skills/check-ok/SKILL.md
A
.claude/skills/deploy-verification-review/SKILL.md
A
.claude/skills/freeze-review-loop/SKILL.md
A
.claude/skills/freeze-review/SKILL.md
A
.claude/skills/governance-sync/SKILL.md
A
.claude/skills/independent-second-reviewer/SKILL.md
A
.claude/skills/print-next/SKILL.md
A
.claude/skills/workspace-status/SKILL.md
A
.cursor/rules/build-verification-required.mdc
A
.cursor/rules/check-ok-thinking.mdc
A
.cursor/rules/governance-sync.mdc
A
.cursor/rules/l1-checkpoints-consumer-owned.mdc
A
.cursor/rules/no-docs-only-pr-to-main.mdc
A
.cursor/rules/orchestrator.mdc
A
.cursor/rules/print-next-closeout.mdc
A
.cursor/rules/tier-authority.mdc
A
.cursor/rules/workspace-authority.mdc
A
.cursor/skills/build-verification-review/SKILL.md
A
.cursor/skills/check-ok/SIDE-CHECK-TEMPLATE.md
A
.cursor/skills/check-ok/SKILL.md
A
.cursor/skills/deploy-verification-review/SKILL.md
A
.cursor/skills/freeze-review-loop/SKILL.md
A
.cursor/skills/freeze-review/SKILL.md
A
.cursor/skills/governance-sync/SKILL.md
A
.cursor/skills/independent-second-reviewer/SKILL.md
A
.cursor/skills/print-next/SKILL.md
A
.cursor/skills/workspace-status/SKILL.md
A
.overseer/STANDING-DECISIONS.reference.md
A
.overseer/config.yaml
A
.overseer/policy/model-labels.yaml
A
.overseer/policy/model-routing.yaml
A
.overseer/policy/test-tiers.yaml
A
.overseer/policy/tiers.yaml
A
.overseer/version.lock
A
docs/MUSE-215-CREATED-BY-FALLBACK-FREEZE.md
A
docs/MUSE-216-BRANCHMETA-CREATED-BY-FREEZE.md
A
docs/MUSE-OVERSEER-HANDOVER.md
A
docs/MUSE-ROADMAP.md
A
tests/test_branch_created_meta.py
M
.museignore
M
CLAUDE.md
M
docs/agent-guide.md
M
docs/agent-provenance.md
M
docs/issues/derive-semver-tag-from-pep440-version.md
M
docs/issues/mwp-mvp-master.md
M
docs/issues/reflog-followup.md
M
docs/issues/symlog-followup.md
M
docs/issues/version-tags-followup.md
M
docs/reference/auth.md
M
docs/reference/plumbing.md
M
docs/reference/reflog.md
M
docs/reference/remotes.md
M
docs/reference/type-contracts.md
M
muse/cli/app.py
M
muse/cli/commands/agent.py
M
muse/cli/commands/agent_config.py
M
muse/cli/commands/auth.py
M
muse/cli/commands/blame.py
M
muse/cli/commands/branch.py
M
muse/cli/commands/bundle.py
M
muse/cli/commands/checkout.py
M
muse/cli/commands/checkout_symbol.py
M
muse/cli/commands/cherry_pick.py
M
muse/cli/commands/clone.py
M
muse/cli/commands/code_stage.py
M
muse/cli/commands/commit.py
M
muse/cli/commands/commit_graph.py
M
muse/cli/commands/diff.py
M
muse/cli/commands/domain_info.py
M
muse/cli/commands/format_patch.py
M
muse/cli/commands/hub/collaborators.py
M
muse/cli/commands/hub/proposals.py
M
muse/cli/commands/hub/releases.py
M
muse/cli/commands/hub/users.py
M
muse/cli/commands/ls_remote.py
M
muse/cli/commands/merge.py
M
muse/cli/commands/migrate_cmd.py
M
muse/cli/commands/mist.py
M
muse/cli/commands/mv.py
M
muse/cli/commands/name_rev.py
M
muse/cli/commands/narrative.py
M
muse/cli/commands/path_cmd.py
M
muse/cli/commands/pull.py
M
muse/cli/commands/push.py
M
muse/cli/commands/read.py
M
muse/cli/commands/read_snapshot.py
M
muse/cli/commands/reflog.py
M
muse/cli/commands/release.py
M
muse/cli/commands/reset.py
M
muse/cli/commands/rev_list.py
M
muse/cli/commands/revert.py
M
muse/cli/commands/status.py
M
muse/cli/commands/switch.py
M
muse/cli/commands/symlog.py
M
muse/cli/commands/tag.py
M
muse/cli/commands/test_cmd.py
M
muse/cli/commands/worktree.py
M
muse/cli/config.py
M
muse/core/agent_slots.py
M
muse/core/blame.py
M
muse/core/commits.py
M
muse/core/domain_migration.py
M
muse/core/gc.py
M
muse/core/graph.py
M
muse/core/hdkeys.py
M
muse/core/identity.py
M
muse/core/keypair.py
M
muse/core/paths.py
M
muse/core/rebase.py
M
muse/core/reflog.py
M
muse/core/semver_classifier.py
M
muse/core/slip010.py
M
muse/core/symlog.py
M
muse/core/test_selection.py
M
muse/core/transport.py
M
muse/core/verify.py
M
muse/core/version_tags.py
M
muse/core/workdir.py
M
muse/plugins/code/_callgraph.py
M
muse/plugins/code/_query.py
M
muse/plugins/code/plugin.py
M
muse/plugins/code/stage.py
M
muse/plugins/registry.py
M
pyproject.toml
M
tests/test_agent_key_fd.py
M
tests/test_agent_seed_zeroing.py
M
tests/test_auth_register_integrity.py
M
tests/test_auth_rotate.py
M
tests/test_auth_show_migrate.py
M
tests/test_auth_supercharge.py
M
tests/test_branch_intent_created_by.py
M
tests/test_branch_json_schema.py
M
tests/test_cli_hub.py
M
tests/test_cmd_agent.py
M
tests/test_cmd_agent_config.py
M
tests/test_cmd_auth_keygen_hd.py
M
tests/test_cmd_auth_keygen_register.py
M
tests/test_cmd_auth_phase8.py
M
tests/test_cmd_branch.py
M
tests/test_cmd_checkout.py
M
tests/test_cmd_cherry_pick_hardening.py
M
tests/test_cmd_code_add.py
M
tests/test_cmd_domain_info.py
M
tests/test_cmd_ls_remote.py
M
tests/test_cmd_read_snapshot.py
M
tests/test_cmd_test.py
M
tests/test_commit_sign_config.py
M
tests/test_core_agent_slots.py
M
tests/test_core_blame.py
M
tests/test_core_hdkeys.py
M
tests/test_core_symlog.py
M
tests/test_core_version_tags.py
M
tests/test_migrate_domain_integers.py
M
tests/test_mist_cli.py
M
tests/test_msign_dual_sig.py
M
tests/test_plugin_registry.py
M
tests/test_reflog_ref_resolution.py
M
tests/test_reflog_supercharge.py
M
tests/test_security_zeroing.py
M
tests/test_sem_ver.py
M
tests/test_status_directory_tracking.py
D
.museagent.md
D
docs/code-test-internals.md
D
docs/code-test.md
D
docs/domain-extensibility.md
D
docs/issues/blame-false-attribution.md
D
docs/issues/issue-1-sign-agent-only.md
D
docs/issues/issue-100-no-way-to-retrieve-own-public-key.md
D
docs/issues/issue-101-files-double-recorded-as-directories.md
D
docs/issues/issue-102-empty-file-misclassified-as-dir-sentinel.md
D
docs/issues/issue-103-cannot-untrack-empty-dir-sentinel-still-on-disk.md
D
docs/issues/issue-104-empty-dir-sentinel-roadmap.md
D
docs/issues/issue-2-sign-silent-failure.md
D
docs/issues/issue-99-agent-keygen-register-key-mismatch.md
D
docs/issues/issue-git-bridge-stale-copy-audit.md
D
docs/issues/snapshot-content-id-migration-plan.md
D
docs/local-dev-safety.md
D
docs/releases/v0.2.0-nightly.3.md
D
muse/cli/commands/fix_snapshot_ids.py
D
muse/cli/commands/hooks.py
D
muse/cli/dev_guard.py
D
muse/core/hooks.py
D
muse/core/hub_scoping_migration.py
D
muse/core/octopus_merge.py
D
muse/core/snapshot_content_migrate.py
D
muse/plugins/chess/__init__.py
D
muse/plugins/chess/plugin.py
D
muse/plugins/timeline/__init__.py
D
muse/plugins/timeline/_otio_bridge.py
D
muse/plugins/timeline/entity.py
D
muse/plugins/timeline/manifest.py
D
muse/plugins/timeline/plugin.py
D
muse/plugins/timeline/rational_time.py
D
muse/plugins/todo/__init__.py
D
muse/plugins/todo/plugin.py
D
scripts/dev/backup-bundle.sh
D
scripts/dev/backup.py
D
scripts/dev/restore.sh
D
scripts/dev/sandbox-refresh.sh
D
scripts/dev/sandbox-run.sh
D
scripts/dev/sandbox.py
D
scripts/dev/snapshot-store.sh
D
scripts/dev/which-muse.sh
D
scripts/dev/which_muse.py
D
scripts/muse-git-backup.sh
D
tests/fixtures/timeline/golden/multi_track.manifest.json
D
tests/fixtures/timeline/golden/single_track.manifest.json
D
tests/fixtures/timeline/identical_shots.otio
D
tests/fixtures/timeline/multi_track.otio
D
tests/fixtures/timeline/ntsc_23976.otio
D
tests/fixtures/timeline/ntsc_2997_df.otio
D
tests/fixtures/timeline/offline_media.otio
D
tests/fixtures/timeline/single_track.otio
D
tests/fixtures/timeline/single_track_reformatted.otio
D
tests/test_apply_manifest_dir_pruning.py
D
tests/test_auth_key_list_delete.py
D
tests/test_auth_show_public_key.py
D
tests/test_backup.py
D
tests/test_binary_separation.py
D
tests/test_blame_symlog_fast_path.py
D
tests/test_cache_invalidation_gaps.py
D
tests/test_cache_status.py
D
tests/test_cache_status_fields.py
D
tests/test_checkout_symbol_symlog_ref.py
D
tests/test_chess_plugin.py
D
tests/test_cmd_branch_copy_reflog.py
D
tests/test_cmd_branch_rename_reflog.py
D
tests/test_cmd_commit_hooks.py
D
tests/test_cmd_commit_hooks_acceptance.py
D
tests/test_cmd_hooks.py
D
tests/test_cmd_hooks_install.py
D
tests/test_cmd_hub_collaborator_accept.py
D
tests/test_cmd_hub_release_list.py
D
tests/test_cmd_reflog_long_ids.py
D
tests/test_cmd_switch_detached_head.py
D
tests/test_cmd_symlog_analytics.py
D
tests/test_cmd_symlog_grep.py
D
tests/test_cmd_symlog_prune_orphans.py
D
tests/test_cmd_symlog_show.py
D
tests/test_cmd_symlog_stat.py
D
tests/test_cmd_tag_list_remote.py
D
tests/test_cmd_tag_sign.py
D
tests/test_comment_only_independence_merge.py
D
tests/test_core_hooks.py
D
tests/test_core_hooks_install.py
D
tests/test_core_hooks_run.py
D
tests/test_dev_guard.py
D
tests/test_diff_pathspec.py
D
tests/test_empty_dir_sentinel_invariants.py
D
tests/test_format_patch_range_shorthand.py
D
tests/test_harmony_merge_commit_integrity.py
D
tests/test_hooks_clone_status_notice.py
D
tests/test_migrate_hub_scoping.py
D
tests/test_narrative_symlog_fast_path.py
D
tests/test_octopus_merge.py
D
tests/test_path_annotate.py
D
tests/test_phase6_acceptance.py
D
tests/test_push_refspec.py
D
tests/test_reflog_anchor.py
D
tests/test_reflog_compact.py
D
tests/test_reflog_diff.py
D
tests/test_reflog_format.py
D
tests/test_reflog_remote_sharing.py
D
tests/test_reflog_stat.py
D
tests/test_reflog_time_resolution.py
D
tests/test_reflog_watch.py
D
tests/test_release_tag_crosslink.py
D
tests/test_reorder_only_semver_classification.py
D
tests/test_revert_symlog.py
D
tests/test_sandbox.py
D
tests/test_security_check_hub_scoped.py
D
tests/test_snapshot_content_migrate.py
D
tests/test_snapshot_content_migrate_cascade.py
D
tests/test_snapshot_content_migrate_refs.py
D
tests/test_symlog_remote_sharing.py
D
tests/test_symlog_time_resolution.py
D
tests/test_tag_reflog.py
D
tests/test_timeline_plugin.py
D
tests/test_timeline_rational_time.py
D
tests/test_todo_plugin.py
D
tests/test_transport_coerce_commit_dict.py
D
tests/test_version_tag_relative_resolution.py
D
tests/test_version_tag_signing.py
D
tests/test_which_muse_script.py
D
tests/test_worktree_reflog.py
Commits
2Divergence Analysis
feat/216-branchmeta-created-by → dev0% divergence
Very compatible — minimal differences
Review comments
1## Review
Reviewed both tickets fresh, then reviewed the real diff line by line (not just the summary).
**The core fix is genuinely good.**
- **#215** — `_created_by_from_record` now tries `agent_id`, then `.author`, sanitizes, returns `None` only if both are empty. Exactly the suggested fix, plus proper control-character stripping.
- **#216** — Real write-once provenance: `stamp_branch_created()` is called from all the actual branch-creation sites (`switch -c`, `checkout -b`, `branch <name>`, `worktree add -b`, branch copy), correctly gated so it only fires on genuine creation, and is write-once (a second stamp call is a no-op once `created_at` exists). `muse branch --json` now reports two separate fields exactly as the ticket asked for: `created_by` (tip authorship, unchanged meaning) and `branch_created_by`/`branch_created_at` (immutable creation record). Rename (`-m/-M`) correctly moves the metadata; force-copy correctly resets it. Test coverage is thorough — 570 lines, 7 tiers including stress/security.
**One real blocker**, found by actually running the suite: `TestStress::test_list_500_branches_fast` fails — **2890ms vs dev's real baseline of 111ms, a ~26x regression**, not a marginal miss. Profiled it: `muse branch --json`'s existing per-branch loop already re-parses the *entire* `config.toml` from scratch on every iteration (a pre-existing O(n²) pattern via `read_branch_meta` → `_load_config`, called ~twice per branch). That was cheap enough to hide when each branch's TOML section was 4 lines; this PR adds 3 more fields per branch, growing the file enough to tip that latent inefficiency into a real, user-visible slowdown. Not something a revert of this PR alone fixes — the O(n²) parse pattern was already there — but this PR is what exposes it, so it needs to be fixed before merging (load `config.toml` once outside the loop, not per-branch).
**Two process issues, separate from the code:**
1. All 4 commits have completely empty `author`/`agent_id`/`signature` — no provenance at all, which violates this project's own commit convention (and is a bit ironic given the subject matter).
2. The branch bundles a large amount of unrelated tooling scaffolding — `.claude/skills/*`, `.cursor/rules/*`, `.cursor/skills/*`, `.overseer/*` — none of which belongs in `muse`. Please strip these before merge.
**Minor:** the `pyproject.toml` merge conflict against current `dev` is trivial (this branch forked from the `0.2.0.dev2` era; `dev` is now at `0.2.1rc4`) — just keep `dev`'s version string, not a real content conflict.
**Recommendation:** not ready to merge as-is. Please: (1) fix the performance regression, (2) drop the unrelated `.claude`/`.cursor`/`.overseer` files, and (3) recommit with real `--agent-id`/`--sign` provenance on every commit.
Muse CLI
Comment
muse hub proposal comment create sha256:4c6ea627bf5ac6b1a687f4200ff1fe4d255bfd699c2449f78fcf0254b2d9c612 --body "…"
Approve
muse hub proposal review submit sha256:4c6ea627bf5ac6b1a687f4200ff1fe4d255bfd699c2449f78fcf0254b2d9c612 --verdict approve
Request changes
muse hub proposal review submit sha256:4c6ea627bf5ac6b1a687f4200ff1fe4d255bfd699c2449f78fcf0254b2d9c612 --verdict request_changes --body "…"
Close
muse hub proposal close sha256:4c6ea627bf5ac6b1a687f4200ff1fe4d255bfd699c2449f78fcf0254b2d9c612
Merge — merge engine docs ↗
Merge
muse hub proposal merge sha256:4c6ea627bf5ac6b1a687f4200ff1fe4d255bfd699c2449f78fcf0254b2d9c612 --hub http://staging.musehub.ai