agentleFS
AnyOrgNameAnyOrgName/php-skills/skills/audit/stack-detection/SKILL.md

stack-detection

Skill4 starsChanged 4 months agoMITView on GitHub

Reconnaissance for a brownfield PHP audit — detect the PHP version, framework(s), Bitrix modules, and CI configuration from composer.json, composer.lock, .env, and Dockerfiles, then emit a structured stack profile for the domain scans that follow. Use when the user asks to analyze a project or codebase (analyze this repo, проанализируй проект, определи стек) before any findings can be gathered; the repository appears to mix frameworks (Laravel plus legacy Bitrix, Symfony plus raw PHP) and the audit must detect every framework present, not just the primary one; the user points at an existing PHP project or codebase and the audit must first discover which PHP version, framework(s), and Bitrix modules are in play. Keywords: audit, report, stack, detection, reconnaissance, recon, brownfield, project, codebase, composer, framework, detect, анализ, проект, стек.

  • Reads credentials

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. About 0 are common, 8 are distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Do not run stack detection when the user asks to fix one specific known bug or feature.

    line 77
  2. Distinctive:

    Verify: You have a resolved PHP version and a list of framework packages with lock line numbers.

    line 134
  3. Distinctive:

    Read the CI workflow, Dockerfile, and .env to confirm the runtime version and services, and for Bitrix list bitrix/modules and read …

    line 135
  4. Distinctive:

    Verify: The runtime version is reconciled with the lock and any Bitrix modules are listed.

    line 137
  5. Distinctive:

    Verify: Each version or framework drift you noticed has a finding with two evidence pointers.

    line 140
  6. Distinctive:

    Verify: The profile is one structured object where every field carries an evidence pointer.

    line 155
  7. Distinctive:

    Verify: The emitted profile states its confidence and is consumed by project-analysis.

    line 159
  8. Very specific:

    Every detected fact must cite the file and line it came from (for example composer.lock:812).

    line 166
  9. Distinctive:

    Not applicable — no I/O, auth, or untrusted input.

    line 204

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md
<!-- generated: do not edit — source: knowledge/atoms/audit/stack-detection/ --><!-- schema: atomVersion=3 skillVersion=2 graphVersion=1 --><!-- compile: @php-skills/compiler v1.0.0 (deterministic build) -->

Audit — Stack Detection

When to use

  • The user asks to analyze a project or codebase (analyze this repo, проанализируй проект, определи стек) before any findings can be gathered.
  • The repository appears to mix frameworks (Laravel plus legacy Bitrix, Symfony plus raw PHP) and the audit must detect every framework present, not just the primary one.
  • The user points at an existing PHP project or codebase and the audit must first discover which PHP version, framework(s), and Bitrix modules are in play.

When NOT to use

  • Do not run stack detection when the user asks to fix one specific known bug or feature; jump straight to that file instead of surveying the whole stack.
  • Skip detection when a fresh, trusted stack profile already exists; reuse it and proceed to the domain scans rather than re-running reconnaissance.

Core guidance

  • Enumerate Bitrix modules and edition from bitrix/modules — For a Bitrix project, list the installed modules under bitrix/modules/ and read bitrix/modules/main/classes/general/version.php for the edition and version so legacy-versus-D7 findings are attributed to the right module.
  • Read CI config, Dockerfiles, and .env for the runtime picture — Parse the CI workflow, Dockerfile/docker-compose.yml, and .env/.env.example to learn the real runtime PHP version, test matrix, extensions, and services, then reconcile them against the composer constraint.
  • Read composer.json and composer.lock before guessing — Start from composer.json (declared PHP constraint, framework requires) and composer.lock (the resolved, installed versions) — the lock file is the source of truth for what actually runs, so trust it over the loose constraint.
  • Identify each framework from its marker package and layout — Map marker packages to frameworks — laravel/framework means Laravel, symfony/framework-bundle means Symfony, bitrix/* or a bitrix/ directory means Bitrix — and record every framework found, not only the largest.

Decision Engine

Walk this section before choosing an implementation path.

What signal is available first — a committed composer.lock, only a loose
composer.json, or a framework directory with no composer at all?

├── composer.json only, no lock: → runtime-confirmed profile — treat the composer.json range as a hint, then confirm
the real version from the CI workflow and Dockerfile before emitting the profile.

├── composer.lock committed: → lock-based profile — read resolved versions from composer.lock, cross-check the
CI matrix, and emit a high-confidence stack-profile artifact.

└── No composer, framework tree only: → fingerprint profile — detect Bitrix from bitrix/modules and version.php, or legacy
PHP from directory layout, and emit a lower-confidence stack-profile flagged as such.

Full engine: references/decision-engine.md — Decision Tree, Priority Matrix, Decision Table.

Workflows

Workflow: Detect Stack

Progress:
- [ ] Open composer.json for the declared PHP constraint and requires, then open
composer.lock and record the resolved php version plus every framework package
- [ ] Read the CI workflow, Dockerfile, and .env to confirm the runtime version and
services, and for Bitrix list bitrix/modules and read version.php for the edition
- [ ] Compare the declared constraint, the resolved lock, and the runtime; every mismatch
becomes an audit finding with evidence pointers for each side of the gap
  1. Open composer.json for the declared PHP constraint and requires, then open composer.lock and record the resolved php version plus every framework package.
    • Verify: You have a resolved PHP version and a list of framework packages with lock line numbers.
  2. Read the CI workflow, Dockerfile, and .env to confirm the runtime version and services, and for Bitrix list bitrix/modules and read version.php for the edition.
    • Verify: The runtime version is reconciled with the lock and any Bitrix modules are listed.
  3. Compare the declared constraint, the resolved lock, and the runtime; every mismatch becomes an audit finding with evidence pointers for each side of the gap.
    • Verify: Each version or framework drift you noticed has a finding with two evidence pointers.

Workflow: Handoff Profile

Progress:
- [ ] Collect the resolved php version, frameworks, Bitrix modules, CI matrix, and
services into one structured profile, attaching a `path:line` pointer to each field
- [ ] Stamp the profile with a confidence level based on its evidence source (lock is
high, CI is medium, fingerprint is low) and emit it as the stack-detected artifact
the domain scans consume
  1. Collect the resolved php version, frameworks, Bitrix modules, CI matrix, and services into one structured profile, attaching a path:line pointer to each field.
    • Verify: The profile is one structured object where every field carries an evidence pointer.
  2. Stamp the profile with a confidence level based on its evidence source (lock is high, CI is medium, fingerprint is low) and emit it as the stack-detected artifact the domain scans consume.
    • Verify: The emitted profile states its confidence and is consumed by project-analysis.

Best practices

  • Produce a stack-detected profile — php version, frameworks with versions, Bitrix modules, CI matrix, key services — each field annotated with the evidence path (path:line) it came from, so the domain scans consume facts, not guesses
  • Every detected fact must cite the file and line it came from (for example composer.lock:812); a claim with no evidence pointer is dropped, not recorded

Anti-patterns

Anti-patternWhy it failsDo instead
Taking the stack from the README instead of the codeDocumentation lags the code, so a README-sourced profile audits a project that no longer exists.Derive every fact from composer.lock, CI, Dockerfiles, and the source tree, using docs only as a cross-check.
Running composer install just to detect the stackInstalling mutates the working tree and can execute untrusted scripts; detection must stay read-only.Read the committed composer.lock and config files directly; never install or execute code just to identify versions.
Skipping recon and scanning blindWithout a known stack, findings are attributed to the wrong framework and version, inflating false positives.Always produce the stack-detected profile first, then let each domain scan consume it.

See references/anti-patterns.md.

Debugging

  1. Recording stack facts with no evidence pointer — Unsourced facts cannot be verified and quietly corrupt every finding built on them. Fix: Attach a path:line evidence pointer to every field; drop any fact you cannot cite rather than guessing it into the profile.
  2. Stopping at the first framework found — The unaudited minority stack is usually where the oldest, riskiest code hides. Fix: Scan for every framework marker (packages and directories) and record each stack found before starting the domain scans.
  3. Trusting the composer.json range as the real version — Every version-specific finding is then wrong — flagging fixed issues or missing real ones. Fix: Read the resolved version from composer.lock and the CI matrix; use the constraint only as a fallback hint when no lock or CI exists.

Production checklist

  • All frameworks are listed, including secondary or legacy stacks, each with its own evidence pointer.
  • The profile states a confidence level so downstream scans know whether facts came from a lock, from CI, or from a fingerprint guess.
  • Each field in the stack profile carries a path or path-and-line evidence pointer to the file it came from.
  • The PHP and framework versions in the profile are read from composer.lock, not the loose composer.json range.
  • The CI and Docker runtime versions are reconciled with the composer constraint and any drift is flagged.

Version notes

  • composer.lock and PHP platform config — composer.lock records platform-overrides and a content-hash; when a config.platform.php override is set, resolved versions may differ from the host PHP, so read the override before trusting the runtime for version-specific findings.

Security

  • Not applicable — no I/O, auth, or untrusted input.

Testing

  • Activation and decision behavior are verified in eval/scenarios/audit/stack-detection.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/project-analysis

<!-- graph-fragment: graph/fragments/audit/stack-detection.yaml -->

Skill contract

Produces: audit.stack-detected
Risk: low · Confidence: 0.9

<!-- contract-fragment: contracts/fragments/audit/stack-detection.yaml -->

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.