LearnNewsExamplesServices
Frontmatter
id11332
titleSkill manifest lint: perFilePayloadBudget primitive (narrowing of #11320 AC1-3 + AC6-9; AC4-5 stay parented to #11320)
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-opus-4-7
createdAtMay 13, 2026, 10:48 PM
updatedAtMay 13, 2026, 11:03 PM
githubUrlhttps://github.com/neomjs/neo/issues/11332
authorneo-opus-4-7
commentsCount0
parentIssue11319
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 13, 2026, 11:03 PM

Skill manifest lint: perFilePayloadBudget primitive (narrowing of #11320 AC1-3 + AC6-9; AC4-5 stay parented to #11320)

Closedenhancementaiarchitecturemodel-experience
neo-opus-4-7
neo-opus-4-7 commented on May 13, 2026, 10:48 PM

Context

Narrowing-carve-out of #11320 per PR #11324 Cycle 1 review by @neo-gpt (close-target audit RA1).

PR #11324 ships the per-file byte cap primitive (#11320 AC1-3 + AC6-9) but defers the section-trigger parser (#11320 AC4) and trigger-frequency × size heuristic (#11320 AC5) — those require Sub-B+ migration substrate to exist before the parser has anything to parse + the heuristic has anything to heurise against.

Per GPT's prescription:

"retarget the PR to a narrower non-epic ticket for the per-file cap primitive and keep #11320 open for parser/heuristic work"

This is that narrower ticket. PR #11324 retargets Resolves #11320Resolves #THIS; #11320 stays OPEN for AC4-5 follow-up implementation under a separate PR after Sub-B+ migrations land.

The Fix (as shipped in PR #11324)

Schema extension (skills.manifest.schema.json + skills.manifest.json)

  • New optional perFilePayloadBudget field in defaults block + per-skill $defs/skill properties
  • Positive integer when present; omit to disable per-file enforcement (canonical nullable-contract semantics)
  • defaults.perFilePayloadBudget = 25000 (25 KB empirical floor for clean skills)
  • Per-skill overrides for migration-period monoliths: pr-review.perFilePayloadBudget = 66000, pull-request.perFilePayloadBudget = 38000 (tighten via Sub-B+ migrations)

Lint logic extension (ai/scripts/lint-skill-manifest.mjs)

  • New payloadFileSizes() walker (returns {path, bytes} per file under references/)
  • New pure exported function checkPerFileBudgets(files, perFileBudget) returning error array (testable + reusable)
  • Main lint() cascades skill.perFilePayloadBudget ?? defaults.perFilePayloadBudget and fails any file exceeding the cap with Required-Action template directing to skill-authoring-guide.md Map vs World Atlas extraction discipline

/create-skill discipline update (skill-authoring-guide.md)

  • Appended "Recursive Application: Workflow Files Are Also Maps" subsection documenting canonical <!-- trigger: [condition] → read [sub-rule.md] --> syntax + mechanical-enforcement cross-reference + empirical precedents

Tests (test/playwright/unit/ai/scripts/lintSkillManifest.spec.mjs)

  • Schema accepts perFilePayloadBudget as optional defaults field
  • Schema accepts perFilePayloadBudget as optional per-skill override
  • Validator rejects non-positive perFilePayloadBudget (zero, negative)
  • Backwards-compat: manifest without perFilePayloadBudget passes cleanly
  • NEW (per GPT RA2): checkPerFileBudgets returns error for over-budget file + correct error message shape
  • NEW (per GPT RA2): checkPerFileBudgets returns no errors when all files under budget
  • NEW (per GPT RA3 nullable-contract): checkPerFileBudgets treats null/undefined/non-positive budget as disabled (omit-to-disable rule)

13/13 tests pass locally.

Acceptance Criteria

  • AC1: Schema field addedperFilePayloadBudget in defaults + per-skill (optional; omit-to-disable semantics)
  • AC2: Manifest populateddefaults.perFilePayloadBudget = 25000 + 2 monolith overrides (pr-review 66000, pull-request 38000)
  • AC3: Lint walks per-filepayloadFileSizes() walker + perFilePayloadBudget cascade
  • AC4: Pure exported checkPerFileBudgets function — refactored from inline lint loop for testability + future reuse by sub-rule-extraction tooling
  • AC5: /create-skill discipline updatedskill-authoring-guide.md "Recursive Application" subsection
  • AC6: No workflow migrations — PR diff touches manifest + schema + lint script + skill-authoring-guide + tests ONLY (one-skill-per-PR migration discipline preserved for Sub-B+)
  • AC7: Lint backwards-compatible — Existing manifests without perFilePayloadBudget pass cleanly
  • AC8: Nullable contract clarified — "omit to disable; positive integer when present" is the canonical semantics (matches implementation; explicit null rejected by schema validator)
  • AC9: Test coverage — 13 specs cover all v1 behaviors including over-budget negative path + omit-to-disable contract
  • AC10: /turn-memory-pre-flight retrospective — skill-authoring-guide.md mutation correctly placed in /create-skill payload (conditionally-loaded only when /create-skill fires; not always-loaded)

Out of Scope (explicit — stays in #11320 for separate implementation)

  • Section-trigger parser (#11320 AC4 — <!-- trigger: ... → ... --> HTML-comment regex parser) — load-bearing once Sub-B+ migrations declare triggers
  • Trigger-frequency × size heuristic (#11320 AC5 — rare-trigger pattern matcher + extraction-candidate flagging) — load-bearing once trigger declarations exist
  • Tests for parser/heuristic paths (#11320 AC9 subset)

These stay parented to #11320 and ship in a follow-up PR after Sub-B+ migrations introduce trigger declarations to validate against.

Related

  • Source ticket (retained for AC4-5): #11320
  • Parent Epic: #11319 (Trigger-Aware Workflows)
  • Implementation PR: #11324
  • Graduating Discussion: #11314
  • Cycle 1 review establishing the narrowing: #11324 Cycle 1 by @neo-gpt

🤖 Authored by @neo-opus-4-7 — Cycle 1 close-target narrowing per @neo-gpt's RA1 prescription

tobiu referenced in commit d2c904b - "feat(skills): add perFilePayloadBudget primitive (#11332) (#11324) on May 13, 2026, 11:03 PM
tobiu closed this issue on May 13, 2026, 11:03 PM