Skip to content

feat: HC-113 — hypercode diff (semantic IR diff)#25

Merged
SoundBlaster merged 7 commits into
mainfrom
feat/hc-113-diff
Jun 12, 2026
Merged

feat: HC-113 — hypercode diff (semantic IR diff)#25
SoundBlaster merged 7 commits into
mainfrom
feat/hc-113-diff

Conversation

@SoundBlaster

Copy link
Copy Markdown
Member

Summary

The last piece of the M8 P0/P1 feature set: hypercode diff <old.ir.json> <new.ir.json> — the invalidation signal for incremental regeneration, as a first-class compiler command.

$ hypercode diff old.ir.json new.ir.json
~ Service > APIServer > Listen
    ~ port: 8080 → 9090
          was: APIServer > Listen @ Examples/service.hcs:26
          now: APIServer > Listen @ /tmp/edited.hcs:26

1 affected node(s)
  • Hash-driven: subtrees with unchanged hashes are skipped wholesale — cost ∝ change, not tree size. Provenance-only changes (different rule, same value) are invisible by design.
  • Reasons included: every property change carries the old and new winning rule with file:line — "which rule changed", per the HC-113 spec.
  • Structure-aware: nodes matched by selector identity (type[.class][#id]); added, removed and reordered children reported distinctly.
  • Machine feed: --format json emits hypercode.diff/v1 for generators; exit code is diff-like (0 identical / 1 changed) for CI gates.
  • Rejects IR v1 with a re-emit hint.

Plumbing: hand-rolled Foundation-free JSON parser (house style — lexer/reader/emitter are all hand-rolled), with numbers kept as raw lexemes so 2^53+1 comparisons stay exact (the lesson from the #23 review applied preemptively). IRDocument read-back model + IRDiffer + renderers in Sources/Hypercode/Diff/.

Stacked on #24. With this PR the release train is complete: explain (#21), IR v2 (#19/#20), contracts (#22), value validation (#23), codegen demo (#24), diff (#25) — all of M8 P0 plus HC-113 and HC-124.

Test plan

  • 15 new tests: value change with both winners, hash short-circuit (unchanged sibling skipped), added/removed/reordered nodes, identity by class/id, provenance-only invisibility, v1 rejection, parser round-trip of emitter output, number lexemes, escapes/surrogates, malformed input, text/JSON rendering — 107 total, 0 failures
  • End-to-end CLI: one-line spec edit → exactly 1 affected node, exit 1; identical docs → exit 0
  • Zero build warnings; codegen demo still green

🤖 Generated with Claude Code

…nal)

New command: hypercode diff <old.ir.json> <new.ir.json> [--format text|json].
Computes the affected-node set between two hypercode.ir/v2 documents:

- hash-driven traversal — a subtree with an unchanged hash is skipped
  wholesale, so cost is proportional to the change, not the tree; a
  provenance-only change (different rule, same value) is invisible by design
- nodes matched by selector identity (type[.class][#id], source order
  disambiguates duplicates); added/removed/reordered children reported
- property changes carry reasons: old/new value plus the old/new winning rule
  ("was: APIServer > Listen @ service.hcs:26 / now: … @ edited.hcs:26")
- --format json emits hypercode.diff/v1 — the machine-readable feed for
  incremental regeneration; exit code is diff-like (0 identical, 1 changed)
- rejects IR v1 with a clear re-emit hint

Plumbing: hand-rolled Foundation-free JSON parser (house style; numbers kept
as raw lexemes so 2^53+1 comparisons stay exact — lesson from the #23 review),
IRDocument read-back model, IRDiffer + text/JSON renderers.

15 new tests (diff semantics incl. hash short-circuit and provenance
invisibility, parser round-trip/escapes/malformed, rendering) — 107 total.
Docs: Usage.md §6 with real output, README CLI block, workplan HC-113 done,
codegen-demo cross-link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cc436644b1

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread Sources/Hypercode/Diff/IRDiffer.swift Outdated
SoundBlaster and others added 4 commits June 12, 2026 12:29
- Schema/hypercode-diff-v1.schema.json — the diff output format is a
  cross-implementation contract like the IR schemas; CI now diffs the example
  IR against an edited spec and ajv-validates the result
- DocC catalog: pipeline updated to v2 + explain/diff, CLI list current,
  Topics sections for Contracts, Explain and Semantic diff symbols
- RFC §9.7: hypercode diff named as the shipped affected-node command;
  0.2 changelog entry gains HC-113
- Usage.md: header pipeline shows diff; §6 links the schema
- README: diff schema linked alongside the IR schemas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…chain

The old text was built on the deprecated "executable architecture language"
framing (explicitly deprecated in DOCS/Positioning.md): a runtime that drives
execution, @profile/@tenant/@feature directives that don't exist, and
enabling/disabling of paths that was never implemented.

Now aligned with RFC 0.2 and reality:
- the one-sentence formula (context-resolved specification layer) and the
  "CSS for application structure" mental model
- real .hcs syntax: selectors, @Dimension[value] contexts, @contract blocks
- the asymmetric-cascade safety lock (values cascade, contracts narrow)
- the resolved IR v2 as the consumer contract (typed values, provenance,
  contracts, Merkle node hashes)
- the actual toolchain table (resolve/validate/explain/emit/diff/lsp)
- review compression + the runnable codegen demo; explicit binding time,
  runtime resolver out of scope per RFC §9.8
- "what it is not" distilled from Positioning.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Review follow-up on #25:
- JSONParser numbers now follow RFC 8259 exactly: no '1.', '1e', '.5',
  leading zeros or non-ASCII digits. diff reads arbitrary files from
  disk, so the boundary is strict.
- Unreadable or non-v2 input exits 2 (GNU diff 'trouble'), no longer
  conflatable with exit 1 'documents differ' in a CI gate.
- The content-only comparison is now explicit: schema description and
  Usage §6 state that context/resolver metadata never participates, and
  the text renderer prints a note when the two contexts differ.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds HC-113 semantic diffing for hypercode.ir/v2 documents, enabling generators/CI to compute an affected-node set (hash-driven) with property-level reasons and an optional machine-readable feed.

Changes:

  • Introduces Sources/Hypercode/Diff/ with a Foundation-free JSON parser, IR v2 read-back model (IRDocument), semantic differ (IRDiffer), and text/JSON renderers.
  • Adds hypercode diff <old.ir.json> <new.ir.json> [--format text|json] to the CLI with diff-like exit codes (0/1/2).
  • Adds hypercode.diff/v1 JSON Schema, updates docs, and extends CI to validate diff output against the schema.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
workplan.md Marks HC-113 as completed with scope details.
Tests/HypercodeTests/IRDiffTests.swift End-to-end tests for diff semantics, parser behavior, and renderers.
Sources/HypercodeCLI/main.swift Adds diff subcommand, argument parsing, exit code conventions, and context-note behavior.
Sources/Hypercode/Documentation.docc/Hypercode.md Documents the new diff capability and public APIs/types.
Sources/Hypercode/Diff/JSONValue.swift Adds JSONValue, JSONParser, and JSONError (Foundation-free, exact number lexemes).
Sources/Hypercode/Diff/IRDocument.swift Adds IR v2 JSON read-back model used by the differ.
Sources/Hypercode/Diff/IRDiffer.swift Implements hash-short-circuit tree diff + text/JSON renderers (hypercode.diff/v1).
Schema/hypercode-diff-v1.schema.json Defines the machine-readable diff feed schema.
RFC/Hypercode.md Updates RFC narrative to include hypercode diff and hypercode.diff/v1.
README.md Adds hypercode diff to top-level CLI usage and schema links.
OVERVIEW.md Updates conceptual overview to include diff in the toolchain story.
Examples/codegen-demo/README.md Mentions hypercode diff as the productized hash comparison.
DOCS/Usage.md Adds a new section documenting hypercode diff behavior, formats, and exit codes.
.github/workflows/swift.yml Adds CI step to emit a diff and validate it against the new schema.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Sources/Hypercode/Diff/JSONValue.swift
SoundBlaster and others added 2 commits June 12, 2026 17:02
…, reject raw control chars

- Duplicate same-label siblings now pair by content hash first inside
  their label group, falling back to source order. A duplicate that
  merely moved reports as childrenReordered instead of two spurious
  property modifications — the invalidation feed no longer marks
  untouched modules stale on a pure swap.
- JSONParser.parseString rejects unescaped U+0000…U+001F (RFC 8259 §7),
  matching the strict number grammar; \r\n is caught despite being a
  single Swift Character.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@SoundBlaster SoundBlaster changed the base branch from feat/hc-124-codegen-demo to main June 12, 2026 14:11
@SoundBlaster SoundBlaster merged commit cd06dee into main Jun 12, 2026
5 checks passed
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