Skip to content

Tighten manifest 25-26, add steps 27-31, relax baseline lock - #479

Merged
Firehed merged 3 commits into
mainfrom
manifest/tighten-25-26
Sep 1, 2026
Merged

Tighten manifest 25-26, add steps 27-31, relax baseline lock#479
Firehed merged 3 commits into
mainfrom
manifest/tighten-25-26

Conversation

@Firehed

@Firehed Firehed commented Sep 1, 2026

Copy link
Copy Markdown
Owner

Follow-up to #473. Scope grew after a second scan surfaced five more M×N patterns not captured by the current manifest, and after the realisation that step-21's baseline hard-lock made new tighten rules impractical.

Tightens to steps 25 and 26

  • step-25 — enumerates the nine node kinds that must gain docblock coverage; notes that if docblockForExpression becomes a one-liner it is deleted and inlined rather than kept as a wrapper.
  • step-26 — names Domain\LateBindingKeyword as the sole home (drops the "or ScopeFinder::resolveClassName, whichever" hedge); adds a tests/Architecture/ test that fails if the three keyword literals appear in src/ outside the enum.

New steps 27-31 for uncaptured M×N findings

Each ships a disallowedMethodCalls tighten modelled on #478's pattern.

  • step-27 — union/intersection receivers: every member-lookup site in ExpressionResolver and MemberAccessDetector picks getResolvableClassNames()[0] while SymbolResolver::getAccessibleMembers iterates. Failure: function f(A|B $x) { $x->onlyB(); } — completion offers onlyB, hover returns null. Tighten pins getResolvableClassNames() to the shared helper.
  • step-28resolveConstFetch uses one lookup, resolveFuncCall iterates NameContext::candidates. Failure: namespace App; const X = 1; echo X; — hover on X returns null. Tighten pins SymbolSource::lookupConstant to ExpressionResolver.
  • step-29SymbolCandidates reads ->docblock + DocblockParser::extractDescription directly, bypassing HasSymbolLocation::getDocumentation(). Preventive today; a future tag-strip in getDocumentation() would silently miss completion detail. Tighten pins DocblockParser::extractDescription to HasSymbolLocation.
  • step-30HoverHandler, SignatureHelpHandler, and CompletionItemFactory each compose format() + getDocumentation() themselves; a ResolvedSymbolPresenter consolidates the shape. Tighten pins the two methods to the presenter.
  • step-31$this typing has an AST path in ExpressionResolver and a text-fallback side-channel in MemberAccessDetector (via a resolvedType node attribute). Deletes the attribute; routes both through one helper. Tighten pins TextFallbackHelper::resolveEnclosingClassName to that helper.

Relaxes bin/check-baseline-shrink NOW

Step-21's script failed if either baseline file existed. That made new tighten rules with residuals impossible to add. Restored the pre-step-21 shrink-only-when-present logic (comparing to origin/main). The hard "must-not-exist" lock moves to the retire step, by which point every interim tighten will have drained its residual.

Beefed-up retire (step-32)

  • Restores the hard lock on bin/check-baseline-shrink.
  • Adds a tests/Architecture/HandlerDependenciesRule.php that fails if any handler in src/Handler/ names ParserService, SymbolIndex, MemberResolver, or SymbolSource directly — code-enforcing the "handlers are formatters, not resolvers" invariant that CLAUDE.md documents but nothing enforces today.
  • Updates CLAUDE.md Guardrails and Architecture Invariants to reflect final state: baselines permanently gone, freeze paragraph deleted, the running list of scoped disallowedMethodCalls tightens named as the seams they pin.

Considered and dropped from the scan

  • Two regex classifiers for call kind (TextFallbackHelper::parseCallPattern vs CompletionClassifier) — verifier confirmed they answer different questions on the same input; no feature asymmetry possible.
  • Two text regex walkers (DefaultTextSymbolExtractor vs TextFallbackHelper::findClassLikeDeclarations) — DefaultTextSymbolExtractor is a consumer of the second; already unified.

PR body written by AI, reviewed by a human.

@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.35%. Comparing base (fd82926) to head (36bfdb1).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##               main     #479   +/-   ##
=========================================
  Coverage     99.35%   99.35%           
  Complexity     1873     1873           
=========================================
  Files           132      132           
  Lines          4805     4805           
=========================================
  Hits           4774     4774           
  Misses           31       31           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

@Firehed Firehed changed the title Tighten steps 25-26 with kind list and LateBindingKeyword pin Tighten manifest 25-26, add steps 27-31, relax baseline lock Sep 1, 2026
@Firehed
Firehed force-pushed the manifest/tighten-25-26 branch from 4b3f39b to 36bfdb1 Compare September 1, 2026 19:39
@Firehed

Firehed commented Sep 1, 2026

Copy link
Copy Markdown
Owner Author

Baseline expansion expected due to the nature of adding more restrictive rules.

@Firehed
Firehed merged commit 80b7bbc into main Sep 1, 2026
8 of 9 checks passed
@Firehed
Firehed deleted the manifest/tighten-25-26 branch September 1, 2026 19:41
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.

1 participant