Skip to content

Match PennMUSH on the behavioural parity steps (Q2) - #2561

Merged
HarryCordewener merged 5 commits into
mainfrom
claude/project-thread-i0ck8e
Nov 6, 2026
Merged

HarryCordewener merged 5 commits into
mainfrom
claude/project-thread-i0ck8e

Conversation

@HarryCordewener

@HarryCordewener HarryCordewener commented Nov 6, 2026 •

Copy link
Copy Markdown
Member

Requested by Grave · project thread

1.0 readiness workstream Q2 (audit-refinement.md §3): the behavioural steps in tools/parity/baseline.json and the KD id hygiene in known-differences.json. Every change was checked against a reference PennMUSH built from upstream with tools/parity/patches applied.

Engine fixes

  • flags() / lflags() with no argument now follow list_all_flags: sorted by name, with internal GOING flags left out. They share FlagListHelpers with @list flags.
  • & on an object the executor does not control is refused before anything is read or written, with @set's refusal (match_controlled, src/cmds.c:1786). Before, it fell through to the attribute writer's #-1 NO PERMISSION TO SET ATTRIBUTE.
  • @suggest/add and /delete print PennMUSH's Suggestion vocabulary word added. / deleted.
  • The unknown-function DID YOU MEAN hint is now PennMUSH's suggest_name: one spellfix1 match at scope 5. The spellfix1 code moved from StringDistanceFunctions to Common/Spellfix.cs, so suggest() and the hint share it. nosuchfunction now suggests MESSAGE and upcstr suggests nothing, as in PennMUSH.
  • spellfix's phonetic hash applies its KN/GN, WR, DJ/DG and TCH rules to lower-case letters only (phoneticHash, src/spellfix.c:204). An unknown function's name is upper-cased before the hint looks it up (src/parse.c:2782). soundex(KNIGHT,phone) is CMACD, as in PennMUSH.
  • loc() and home() return the dbref, not the objid (safe_dbref). loc() of a miss returns #-1. name(), get() and xget() of a miss return #-1 NO SUCH OBJECT VISIBLE.
  • inventory shows an item's dbref only when unparse_object would: examine, link-to, JUMP_OK, CHOWN_OK or DESTROY_OK.

Softcode that compared loc() with an objid

  • Scene package 1.19.1. The web compose verbs now compare objid(loc(%#)) with scene(<id>,room), which is still an objid. Without this, a pose composed on the web never reached the room, and +scene/ooc skipped the room's Speech lock.
    • New test WebComposeOoc_InTheScenesRoom_HonoursItsSpeechLock fails without the fix.
    • The existing WebCompose_EmitsToTheRoom_WhenThePoserIsStandingInIt also fails without it.
  • room-contents 1.3.1. Comment change only; it already reads locations through num().
  • Charge sheet. SharpMUSH.Packages had the same comparison, fixed in sheet-charge 1.2.3: compare an encounter's room by objid SharpMUSH.Packages#95. That fix works with loc() both before and after this PR.

Harness

  • sc.control: the ulocal() case now uses an attribute. PennMUSH accepts #lambda only in ulambda() (src/funufun.c:219), so the old step tested that rule and not register scoping.

  • ff.numeric: median()/mean() now run with null_eq_zero off, then restore it. PennMUSH's mush.cnf ships it off; SharpMUSH's documented default is on.

  • sc.errors: a new step covers the case-sensitive hash.

  • The second KD-0011 is now KD-0005. load_allowlist refuses an id used twice, with a unit test.

  • New pinned entries KD-0043 to KD-0048, each under an existing A choice. profile heading:

    • the & refusal reason (two entries);
    • the inventory pennies line;
    • look Gadget after the restricted @destroy (follows KD-0005);
    • the S of SCENE_ROOM in flags();
    • the @purge/confirm and deposit lines in dbref.holes.

    The economy and SharpMUSH-only-flags profile entries now mention these.

Baseline: 74 → 60 entries. 8 steps now match outright, and 6 are allowlisted with both sides pinned.

Left in the baseline

  • admin.wizard#3 (examine *Alice) has several unrelated differences:
    • Pennies;
    • the Channels line;
    • the Last modified/Quota lines vs RQUOTA;
    • LASTPAGER;
    • LASTSITE 127.0.0.1:<port> vs localhost. This is the connection host, which belongs to Q1.
  • admin.search#2 (@stats): SharpMUSH's world has its own system and package objects (8 things, 1 player). It needs a decision: add a profile entry, or change the case.
  • dc.colours#2 (decompose(ansi(+red,x))): MarkupString's AnsiColor has no named-colour case, so the name is lost before decompose sees it. It needs a MarkupString change.

Also noticed, not changed: u() and ulocal() accept #lambda, which PennMUSH accepts only in ulambda(). No package relies on it.

Testing

  • python3 -m unittest discover -s tools/parity/tests: 51 pass.
  • tools/parity/run.sh --baseline, run after the last engine change: 871 match, 48 known differences, 60 open gaps, 0 new differences. The one ERROR is 75-http. The reference PennMUSH in this container answers @http with "Command disabled.", so it is an environment issue.
  • Full suite at f1a18c0:
    • SharpMUSH.Tests: 21,653 tests, 0 failed. The Packages chunk was rerun after the index version bump: 918 tests, 0 failed.
    • SharpMUSH.Tests.Integration: 1,091 tests, 0 failed.
  • Two independent review passes. The first found the scene package regression and the spellfix case gap; both are fixed here. The second found no correctness issues.

Generated by Claude Code

Fixes, each checked against the reference PennMUSH in tools/parity:
- flags() and lflags() with no argument list what list_all_flags lists:
  sorted by name, never the internal GOING flags.
- & refuses an object the executor does not control before reading or
  writing, with @set's refusal (match_controlled, src/cmds.c:1786).
- @suggest/add and /delete answer with PennMUSH's lines.
- An unknown function's DID YOU MEAN hint is suggest_name's spellfix1
  match at scope 5, shared with suggest() through Common/Spellfix.
- loc() and home() write the dbref, never the objid; loc() of a miss is
  #-1; name(), get() and xget() of a miss are #-1 NO SUCH OBJECT VISIBLE.
- inventory shows an item's dbref only when unparse_object would.

Harness:
- The ulocal() case uses an attribute: PennMUSH takes #lambda only in
  ulambda(). The median()/mean() case sets null_eq_zero off around
  itself, as PennMUSH's mush.cnf has it.
- The duplicate KD-0011 is KD-0005, and the allowlist refuses an id used
  twice. Six steps whose only difference is a documented choice are
  allowlisted with both sides pinned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7UANHQ73A3Wsib6mkh
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7UANHQ73A3Wsib6mkh
@coderabbitai

coderabbitai Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

  • Run on-demand review

This review includes 41 billable files and costs up to $10.25.

  • Ask an admin to make reviews automatic

Open in CodeRabbit

Reviews can continue after your included limit without a manual trigger. An admin must approve usage-based billing.

Or wait 25 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 60 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Essentials
  • Run ID: 734983ae-ece8-4bfe-9770-c3e12081ec8e
Commits

Reviewing files that changed from the base of the PR and between cfa5af9 and f1a18c0.

Files selected for processing: 41

  • SharpMUSH.Documentation/Helpfiles/SharpMUSH/compatibility-economy.md
  • SharpMUSH.Documentation/Helpfiles/SharpMUSH/compatibility-names.md
  • SharpMUSH.Implementation/Commands/InteractionCommands.cs
  • SharpMUSH.Implementation/Commands/PlayerAdminCommands.cs
  • SharpMUSH.Implementation/Commands/SingleTokenCommands.cs
  • SharpMUSH.Implementation/Common/FlagListHelpers.cs
  • SharpMUSH.Implementation/Common/Spellfix.cs
  • SharpMUSH.Implementation/Functions/AttributeFunctions.cs
  • SharpMUSH.Implementation/Functions/DbrefFunctions.cs
  • SharpMUSH.Implementation/Functions/InformationFunctions.cs
  • SharpMUSH.Implementation/Functions/StringDistanceFunctions.cs
  • SharpMUSH.Implementation/Visitors/EvaluationDiagnostics.cs
  • SharpMUSH.Library/Definitions/ErrorMessages.cs
  • SharpMUSH.Library/Resources/Notifications.resx
  • SharpMUSH.Plugins.Scene/Functions/SceneFunctions.cs
  • SharpMUSH.Plugins.Scene/help/scene-functions.md
  • SharpMUSH.Tests.Integration/Integration/SceneWebComposeIntegrationTests.cs
  • SharpMUSH.Tests.Integration/Packages/ScenePackageTests.cs
  • SharpMUSH.Tests.Integration/Scene/SceneServiceIntegrationTests.cs
  • SharpMUSH.Tests/Commands/AttributeCommandTests.cs
  • SharpMUSH.Tests/Commands/AttributeTreePatternVisibilityTests.cs
  • SharpMUSH.Tests/Commands/InventoryFormatTests.cs
  • SharpMUSH.Tests/Commands/MuxCommandTests.cs
  • SharpMUSH.Tests/Commands/TelDiagnosticTests.cs
  • SharpMUSH.Tests/Commands/WizardCommandTests.cs
  • SharpMUSH.Tests/Functions/CommunicationFunctionSpeechLockTests.cs
  • SharpMUSH.Tests/Functions/DbrefFunctionUnitTests.cs
  • SharpMUSH.Tests/Functions/FlagFunctionUnitTests.cs
  • SharpMUSH.Tests/Functions/ParserBehaviorUnitTests.cs
  • SharpMUSH.Tests/Functions/SoundFunctionUnitTests.cs
  • SharpMUSH.Tests/Parser/BracketEvaluationGuideTests.cs
  • docs/softcode/room-contents-handler.md
  • examples/packages/index.yaml
  • examples/packages/room-contents/package.yaml
  • examples/packages/scene/package.yaml
  • tools/parity/baseline.json
  • tools/parity/known-differences.json
  • tools/parity/parity/compare.py
  • tools/parity/scenarios/30-softcode.scn
  • tools/parity/scenarios/35-function-families.scn
  • tools/parity/tests/test_parity.py
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

loc() now answers #N as PennMUSH does, so assertions that matched an
objid read objid(loc(...)), and the guide's smile() example expects the
CNAME suggestion PennMUSH gives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7UANHQ73A3Wsib6mkh
loc() answers with the bare dbref, so the scene package's co-location
tests compare objid(loc(%#)) against scene(<id>,room). Without it a
web-composed pose never reached the room and +scene/ooc skipped the
room's Speech lock. Scene package 1.19.1.

spellfix's phonetic hash applies its KN/GN, WR, DJ/DG and TCH rules to
lower-case letters only, and an unknown function's name is upper-cased
before the DID YOU MEAN lookup, as PennMUSH does: soundex(KNIGHT,phone)
is CMACD.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7UANHQ73A3Wsib6mkh
The handler already reads every location through num(). room-contents
1.3.1; the index carries it and scene 1.19.1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7UANHQ73A3Wsib6mkh
@HarryCordewener
HarryCordewener marked this pull request as ready for review November 6, 2026 20:11
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Codex Review Summary: ✅ Completed

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-06T20:14:06.986429Z f1a18c0 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@HarryCordewener
HarryCordewener merged commit 05cbd0c into main Nov 6, 2026
27 checks passed
HarryCordewener pushed a commit that referenced this pull request Nov 6, 2026
The parity baseline keeps main's three remaining steps after #2561.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rqqt7Uw1NrPpHW2neUJepv
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