kernel-main-module
Skill4 starsChanged 4 months agoMITView on GitHub
Work with the 1C-Bitrix `main` module kernel — bootstrap, the D7 Application / Context / Request services versus the legacy $APPLICATION / CMain globals, the event system, module inclusion, the service locator, and agents. Use when the user needs kernel bootstrap services in Bitrix — `Application::getInstance()`, the `Context`, the `Request`, the connection pool, or the service locator; the user wants to register or handle a Bitrix event — the D7 `EventManager`/`addEventHandler` or the legacy `RegisterModuleDependences`; the user needs to include a Bitrix module or connect code to the kernel — `Loader::includeModule()` (D7) or the legacy `CModule::IncludeModule()`; the user reads HTTP input in Bitrix and asks whether to use the D7 `Context::getRequest()` accessors or the legacy `$_REQUEST`/`$_GET` superglobals. Keywords: bitrix, kernel, main-module, d7, legacy, events, service-locator, input, security, битрикс, ядро.
In this repository119 other files it gives its agents.
- strategy-bitrix-d7-incrementalSkill
- strategy-explicit-over-magicSkill
- strategy-framework-conventionsSkill
- strategy-legacy-safe-editsSkill
- strategy-minimal-diffSkill
- strategy-no-untested-refactorSkill
- strategy-preserve-public-apiSkill
- strategy-readonly-immutabilitySkill
- strategy-security-firstSkill
- strategy-test-drivenSkill
- openapiSkill
- paginationSkill
- rest-designSkill
- versioningSkill
- cqrsSkill
- dependency-inversionSkill
- hexagonalSkill
- repository-patternSkill
- service-layerSkill
- bitrixSkill
- findings-reportSkill
- laravelSkill
- performanceSkill
- phpSkill
- project-analysisSkill
- refactoringSkill
- roi-prioritizationSkill
- securitySkill
- stack-detectionSkill
- cache-layersSkill
- component-engineSkill
- d7-eventsSkill
- d7-loaderSkill
- d7-orm-queriesSkill
- iblock-elementsSkill
- localizationSkill
- controllersSkill
- ormSkill
- validationSkill
- controllersSkill
- query-builderSkill
- routingSkill
- autoload-psr4Skill
- dependency-managementSkill
- scriptsSkill
- connection-poolingSkill
- mysql-indexingSkill
- redisSkill
- transactionsSkill
- ci-github-actionsSkill
- deployment-strategiesSkill
- docker-phpSkill
- env-configSkill
- associationsSkill
- entities-mappingSkill
- orm-basicsSkill
- entity-apiSkill
- module-developmentSkill
- routing-controllersSkill
- formsSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 85
Do not use this skill for pure content editing or template HTML/CSS work that does not touch kernel services, events, module inclusion, or …
- Distinctive: line 87
Do not use this skill on a non-Bitrix PHP app (plain PHP, Laravel, Symfony).
- Very specific: line 135
Verify: $em is a non-null EventManager instance.
- Distinctive: line 139
Verify: The handler appears in the event map and fires on login.
- Distinctive: line 142
Verify: The handler reads its payload from the Event object, not global state.
- Very specific: line 155
Ensure the kernel is bootstrapped, then get the app with $app = \Bitrix\Main\Application::getInstance();.
- Very specific: line 157
Verify: $app is a non-null Application instance.
- Very specific: line 160
Verify: $request->getQuery('id') returns the query value without touching $_GET.
- Distinctive: line 163
Verify: Invalid input is rejected before any query runs.
- Very specific: line 167
Use Bitrix agents (CAgent::AddAgent) for periodic tasks that must run inside a bootstrapped kernel.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
<!-- generated: do not edit — source: knowledge/atoms/bitrix/kernel-main-module/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->Bitrix Kernel (main module)
When to use
- The user needs kernel bootstrap services in Bitrix —
Application::getInstance(), theContext, theRequest, the connection pool, or the service locator. - The user wants to register or handle a Bitrix event — the D7
EventManager/addEventHandleror the legacyRegisterModuleDependences. - The user needs to include a Bitrix module or connect code to the kernel —
Loader::includeModule()(D7) or the legacyCModule::IncludeModule(). - The user reads HTTP input in Bitrix and asks whether to use the D7
Context::getRequest()accessors or the legacy$_REQUEST/$_GETsuperglobals.
When NOT to use
- Do not use this skill for pure content editing or template HTML/CSS work that does not touch kernel services, events, module inclusion, or request handling.
- Do not use this skill on a non-Bitrix PHP app (plain PHP, Laravel, Symfony);
the
mainmodule and its globals do not exist outside 1C-Bitrix.
Core guidance
- Prefer D7 kernel API for new code — In new code, reach for the D7 API first —
\Bitrix\Main\Application,Context,HttpRequest,Loader::includeModule()— instead of$APPLICATION,CMain, orCModule::IncludeModule(). - Read input through the kernel Request, not superglobals — Read HTTP input via
Application::getInstance()->getContext()->getRequest()and its typed accessors (->getQuery(),->getPost()) rather than touching$_GET/$_POSTdirectly.
Decision Engine
Walk this section before choosing an implementation path.
Are you writing new kernel code, or editing an existing legacy code path?
├── Editing legacy path: → legacy — keep the existing legacy API and make a minimal local edit; do not rewrite to D7 opportunistically.
└── New code: Does the API you need exist in the D7 namespace (\Bitrix\Main\...)?
├── D7 exists: → d7 — use Application/Context/Request, Loader::includeModule, and EventManager.
└── No D7 equivalent: → legacy — call the legacy API (e.g. CMain method) behind a thin adapter so call sites stay D7-shaped.
Full engine: references/decision-engine.md — Decision Tree, Priority Matrix, Decision Table.
Workflows
Workflow: Register Event D7
Progress:
- [ ] Get the manager with
`$em = \Bitrix\Main\EventManager::getInstance();` inside the module `init.php`
- [ ] Register with
`$em->addEventHandler('main', 'OnAfterUserLogin', [MyHandler::class, 'onLogin']);`
pointing at a static method
- [ ] In the handler, accept a `\Bitrix\Main\Event $event` and read parameters with
`$event->getParameter('USER');` instead of relying on positional arguments- Get the manager with
$em = \Bitrix\Main\EventManager::getInstance();inside the moduleinit.php.- Verify:
$emis a non-null EventManager instance.
- Verify:
- Register with
$em->addEventHandler('main', 'OnAfterUserLogin', [MyHandler::class, 'onLogin']);pointing at a static method.- Verify: The handler appears in the event map and fires on login.
- In the handler, accept a
\Bitrix\Main\Event $eventand read parameters with$event->getParameter('USER');instead of relying on positional arguments.- Verify: The handler reads its payload from the Event object, not global state.
Workflow: Read Request D7
Progress:
- [ ] Ensure the kernel is bootstrapped, then get the app with
`$app = \Bitrix\Main\Application::getInstance();`
- [ ] Get the request via `$request = $app->getContext()->getRequest();` and read a
value with `$request->getQuery('id')`, treating it as untrusted
- [ ] Validate the raw value at the boundary (e.g- Ensure the kernel is bootstrapped, then get the app with
$app = \Bitrix\Main\Application::getInstance();.- Verify:
$appis a non-null Application instance.
- Verify:
- Get the request via
$request = $app->getContext()->getRequest();and read a value with$request->getQuery('id'), treating it as untrusted.- Verify:
$request->getQuery('id')returns the query value without touching $_GET.
- Verify:
- Validate the raw value at the boundary (e.g. cast to int and reject non-positive
ids) before passing it into domain or ORM calls.
- Verify: Invalid input is rejected before any query runs.
Best practices
- Use Bitrix agents (
CAgent::AddAgent) for periodic tasks that must run inside a bootstrapped kernel; move heavy or precisely-timed jobs to OS cron running an agent script withdefine('BX_CRONTAB', true) - Register new handlers with
EventManager::getInstance()->addEventHandler()(or the module.phpevent map) and keep legacyRegisterModuleDependencesonly for old events that have no D7 counterpart - Guard every
Loader::includeModule('iblock')(or legacyCModule::IncludeModule) with a check on its boolean return and bail early when the module is missing - Resolve shared services with
ServiceLocator::getInstance()->get('code')and register them in.settings.phpinstead of instantiating singletons by hand
Anti-patterns
| Anti-pattern | Why it fails | Do instead |
| New code leaning on $APPLICATION globals | Global state is implicit, untestable, and couples new code to legacy bootstrap order. | Resolve services through Application::getInstance() and the Context; keep the<br>legacy globals only inside legacy files you are not refactoring. |
| Opportunistic D7 rewrite during an unrelated fix | The rewrite widens the diff and risks changing behavior the task never intended to touch. | Keep the scoped fix minimal; propose the D7 migration as a separate, signed-off task. |
| Ignoring the module inclusion result | When the module is absent the call returns false and the next class reference fatals. | Branch on the boolean result and stop with a clear message if the module is missing. |
See references/anti-patterns.md.
Debugging
- Time-critical agent drifts under low traffic — Agents without cron are scheduled by page hits, not by wall-clock time. Fix: Run agents from OS cron with
define('BX_CRONTAB', true)for time-critical jobs so execution no longer depends on incoming traffic. - Accessing Application before the kernel is bootstrapped — The Application singleton and Context are only populated after the prolog bootstraps them. Fix: Bootstrap the kernel (prolog for web, or the documented CLI bootstrap with
define('NO_KEEP_STATISTIC', true)and the agent/cron entry) before touching services. - Trusting raw superglobals in kernel code — Scattered superglobal access hides the input boundary and invites injection and test gaps. Fix: Read through
Context::getRequest()accessors and validate the value at the boundary before it reaches domain logic. - Using module classes before including the module — Autoloading for a module is only wired up after the module is included. Fix: Include the module first and check the boolean result; only then reference its classes, returning a handled error if inclusion fails.
Production checklist
- New event handlers are registered through the EventManager or the module event
map, not scattered inline in templates or
init.phpwith duplicate registrations. - Edits to legacy code paths are minimal and reversible, with no opportunistic rewrite of a working legacy API into D7 during an unrelated change.
- Every
Loader::includeModule()result is checked and the code bails out cleanly when a required module is not installed. - New code does not add fresh dependencies on
$APPLICATION,$USER, or$DBglobals; it resolves the D7 equivalents (Application,CurrentUser, connection). - HTTP input is read through the kernel Request accessors and validated at the
boundary rather than pulled directly from
$_GET/$_POST.
Version notes
- D7 core API arrived with the D7 platform — The namespaced D7 kernel (
\Bitrix\Main\Application,Context,Loader,EventManager) became the recommended core API from the D7 platform (main ~14+); older projects mix it with the legacyC*classes. - PHP support tracks the Bitrix core version — Modern Bitrix cores run on PHP 7.4 through 8.2; the kernel and stock modules were not certified past 8.2 at the time of writing, so avoid relying on PHP 8.3+ syntax in kernel-adjacent code.
Security
- Validate kernel request input at the boundary — Treat every value from the kernel Request (
getQuery,getPost,getCookie) as untrusted: validate and cast it at the controller boundary, and never pass a raw request value straight into SQL, filesystem, oreval-like calls.
Testing
- Activation and decision behavior are verified in
eval/scenarios/bitrix/kernel-main-module.yaml.
Additional resources
- references/anti-patterns.md
- references/core.md
- references/decision-engine.md
- references/examples.md
- references/pitfalls.md
- references/recipes.md
- references/version-differences.md
Knowledge graph
Related: audit/bitrix, bitrix/cache-layers, php/class-constants
Behavior constraints: ai-rules/strategy-legacy-safe-edits
<!-- graph-fragment: graph/fragments/bitrix/kernel-main-module.yaml -->Skill contract
Produces: bitrix.kernel-bootstrapped
Requires: stack.bitrix
Risk: medium · Confidence: 0.9
<!-- contract-fragment: contracts/fragments/bitrix/kernel-main-module.yaml -->Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

