PHPackages                             voku/agent-learning - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. voku/agent-learning

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

voku/agent-learning
===================

Reviewable finding, proposal, redaction, and decision-history tooling for coding-agent learning loops.

0.8.4(1w ago)2323[1 issues](https://github.com/voku/agent-learning/issues)[2 PRs](https://github.com/voku/agent-learning/pulls)1MITPHPPHP ^8.3CI passing

Since Jun 9Pushed 4d agoCompare

[ Source](https://github.com/voku/agent-learning)[ Packagist](https://packagist.org/packages/voku/agent-learning)[ Docs](https://github.com/voku/agent-learning)[ RSS](/packages/voku-agent-learning/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (6)Versions (19)Used By (1)

Coding Agent | Learning-Loops
=============================

[](#coding-agent--learning-loops)

Reviewable finding, proposal, redaction, and decision-history tooling for coding-agent learning loops.

This library provides core domain logic and validation classes to support structured post-session learning for coding agents. It separates raw experiences (Findings) from potential guideline changes (Proposals), keeping the agent's knowledge extraction workflow structured, secure, and fully auditable.

---

Key Concepts
------------

[](#key-concepts)

### Findings

[](#findings)

A **Finding** represents a single raw experience or observation captured from a task session. It stores:

- An observation and a hypothetical rule or pattern.
- A confidence level.
- Explicit validation metadata (`unverified`, `validated`, `invalidated`).
- A validated conclusion detailing why the pattern was verified or rejected.
- Optional learning triage metadata:
    - `classification`: `CREATE_SKILL`, `UPDATE_SKILL`, `ADD_LEARNING_NOTE`, or `IGNORE`.
    - `pattern_key`: stable dot-separated clustering key such as `tests.add_before_change`.
    - `validation_case`: concrete `given` / `when` / `then` behavior check.

`ADD_LEARNING_NOTE` is the default durable capture. `CREATE_SKILL` should be rare; prefer `UPDATE_SKILL` when an existing skill already owns the behavior. `IGNORE` is valid for praise, vague reflection, one-off details, and already-covered guidance.

### Proposals

[](#proposals)

A **Proposal** defines a potential durable mutation to the repository's guidelines or instructions (e.g., in `MEMORY.md` or dedicated agent skills).

- Can represent actions like `ADD`, `DELETE`, `REPLACE`, `REJECT`, or `NO_DURABLE_LEARNING`.
- References one or more validated source findings that back it up.
- Contains metadata about target type, scope, proposed boundary, validation checklist, status, and approval.
- May carry the same `learning_decision`, `pattern_key`, and `validation_case` fields used by consolidation. `CREATE_SKILL` proposals additionally require an `overlap_check` proving existing skills were inspected and no overlapping skill owns more than 50% of the behavior.

### Constraint Specifications

[](#constraint-specifications)

A **ConstraintSpecification** is a typed, reviewable bridge from confirmed learning to executable validation. Constraint proposals describe the engine, rule identifier, scope, objective violation, allowed boundaries, false-positive risk, validation commands, local example rules, target rule path, and registration files. The package validates whether the learning is stable and precise enough for a later PHPStan, PHP-CS-Fixer, test, or CI generation step.

### Evidence

[](#evidence)

Findings must be backed by concrete, verifiable evidence. Supported types include:

- `file_reference`: References to specific files and line numbers.
- `commit`: Reference to a specific git commit.
- `test_result` / `phpstan_result`: Command execution command and summary.
- `review_comment`: Pull/merge request comments or reviews.
- `issue_reference`: Bounded issue or ticket tracker reference.
- `agent_history_reference`: Bounded reference to inspected local agent-history evidence discovered with ctx.
- Others (e.g., `schema_reference`, `runtime_observation`, `manual_verification`).

### Using ctx as historical evidence

[](#using-ctx-as-historical-evidence)

`agent-learning` does not index agent history itself. If [ctx](https://github.com/ctxrs/ctx) is installed, use it before writing findings to discover relevant prior sessions, failed attempts, rejected approaches, and validation history.

ctx hits are evidence references, not durable memory. Record only bounded summaries and ctx IDs in findings. Durable learning still flows through validated findings, proposals, and reviewed decisions.

ctx helps find what happened before; agent-learning decides what deserves to survive.

See [docs/ctx-integration.md](docs/ctx-integration.md) for the evidence schema and the local-history boundary. The related package skill is `agent-learning-ctx-evidence`; the ctx-side search skill is `ctx-agent-history-search`.

### Decision History

[](#decision-history)

A persistent record of approved or rejected proposals stored in JSON Lines (`.jsonl`) format.

- `decisions.jsonl` logs approved and applied mutations.
- `rejected-proposals.jsonl` logs rejected candidate proposals with detailed reasons.

---

Core Classes &amp; APIs
-----------------------

[](#core-classes--apis)

The package codebase is organized under the `voku\AgentLearning` namespace in the following structure:

### Value Objects &amp; Enums

[](#value-objects--enums)

- [Finding](src/Finding.php): Read-only entity representing a captured session finding.
- [FindingStatus](src/FindingStatus.php): Enum defining finding lifecycles (`candidate`, `validated`, `invalidated`, `rejected`, `superseded`, `consolidated`, `archived`).
- [Proposal](src/Proposal.php): Read-only entity representing a proposed modification to guidelines.
- [ProposalStatus](src/ProposalStatus.php): Enum defining proposal states (`candidate`, `approved`, `rejected`, `applied`, `retired`).
- [Action](src/Action.php): Enum representing actions (`NO_DURABLE_LEARNING`, `ADD`, `DELETE`, `REPLACE`, `REJECT`).
- [ConstraintSpecification](src/ConstraintSpecification.php): Read-only model for hard-constraint promotion candidates.
- [GuidanceUsageSummary](src/GuidanceUsageSummary.php): Read-only projection of recall eligibility, selection, application, explicit outcomes, task spread, timestamps, and evidence event IDs.
- [ConstraintEngine](src/ConstraintEngine.php): Enum defining supported hard-constraint engines (`phpstan`, `php_cs_fixer`, `test`, `ci`).
- [Detectability](src/Detectability.php): Enum describing whether the violation is statically, syntax-locally, runtime, or cross-file detectable.
- [FalsePositiveRisk](src/FalsePositiveRisk.php): Enum declaring expected false-positive risk (`low`, `medium`, `high`, `unknown`).

### Parsers &amp; Repositories

[](#parsers--repositories)

- [FindingParser](src/FindingParser.php): Parses a finding JSON record or file.
- [ProposalParser](src/ProposalParser.php): Parses a proposal JSON record or file.
- [FindingRepository](src/FindingRepository.php): Loads validated findings from root directories.
- [ProposalRepository](src/ProposalRepository.php): Loads proposals under different lifecycle folders.
- [RecallSelectionEventRepository](src/RecallSelectionEventRepository.php): Loads immutable recall-selection JSONL events produced by `voku/agent-recall-compiler`.
- [GuidanceOutcomeEventRepository](src/GuidanceOutcomeEventRepository.php): Loads immutable per-guidance outcome JSONL events.

### Validators

[](#validators)

- [FindingValidator](src/FindingValidator.php): Enforces structure, format, and lifecycle consistency for findings.
- [ProposalValidator](src/ProposalValidator.php): Validates proposal mutations, targets, actions, and references.
- [EvidenceValidator](src/EvidenceValidator.php): Inspects list of evidence objects to ensure required fields for each type exist.
- [JsonlValidator](src/JsonlValidator.php): Parses and validates JSON Lines log formats.
- [RedactionGuard](src/RedactionGuard.php): Scans all content for credentials, secrets, or sensitive configuration keys to prevent accidental leaks.
- [DecisionHistoryValidator](src/DecisionHistoryValidator.php): Validates log consistency of the decision history.
- [ConstraintPromotionValidator](src/ConstraintPromotionValidator.php): Validates that constraint proposals come from confirmed findings and contain explicit promotion-gate evidence.
- [ConstraintManifestActivator](src/ConstraintManifestActivator.php): Writes the active manifest consumed by recall tooling after an approved or applied constraint rule exists in the project.

### Utilities &amp; Infrastructure

[](#utilities--infrastructure)

- [ConsolidationPromptBuilder](src/ConsolidationPromptBuilder.php): Assembles validated findings and rejected proposals history into a structured LLM consolidation prompt.
- [ConstraintGenerationPackageExporter](src/ConstraintGenerationPackageExporter.php): Exports `specification.json`, source findings/proposals, examples, validation plan, and generation prompt for coding-agent rule generation.
- [ConstraintLoopRunner](src/ConstraintLoopRunner.php): Drives the approved generated-rule close-out path by exporting, applying, and activating a hard constraint with one explicit command.
- [GuidanceUsageProjector](src/GuidanceUsageProjector.php): Rebuilds deterministic usage summaries from immutable event histories without mutable counters.
- [GuidanceEvolutionEvaluator](src/GuidanceEvolutionEvaluator.php): Applies conservative tier-specific promotion and review policies.
- [RecordAccess](src/RecordAccess.php): Utility helper to extract strongly typed fields from raw array data.
- [Json](src/Json.php): Helper for decoding files safely.
- [ValidationException](src/ValidationException.php): Custom runtime exception with file name, line numbers, and record IDs context.

---

Validation Specifications
-------------------------

[](#validation-specifications)

### Finding Validation

[](#finding-validation)

1. **Finding ID**: Must match `finding.YYYY-MM-DD.NNN`.
2. **Created At**: Must be a valid ISO 8601/Atom timestamp string.
3. **Task ID**: Must match the configured task ID pattern (passed via `$taskIdPattern` to the [FindingValidator](src/FindingValidator.php) constructor; defaults to `'/^(?:[A-Z][A-Z0-9_-]*-\d+|TODO@[\w:\/.-]+)$/'`).
4. **Observation/Hypothesis Separation**: Both must be non-empty strings and cannot be identical.
5. **Confidence**: Must be one of `low`, `medium`, or `high`.
6. **Validation Status**: Must be one of `unverified`, `validated`, or `invalidated`.
7. **Lifecycle Enforcements**:
    - `candidate` requires `validation_status=unverified`.
    - `validated` and `consolidated` require `validation_status=validated`.
    - `invalidated` requires `validation_status=invalidated`.
    - `superseded` and `rejected` require `validation_status=validated` or `validation_status=invalidated`.
    - `archived` preserves the prior validation state and may use any supported `validation_status`.
    - A `validation_status=validated` finding requires a non-empty `validated_conclusion`.
    - The `validated_conclusion` must not be identical to the hypothesis.

### Proposal Validation

[](#proposal-validation)

1. **Proposal ID**: Must match `proposal.YYYY-MM-DD.NNN`.
2. **Created At**: Must be a valid ISO 8601/Atom timestamp string.
3. **Mutations Constraint**: Fields `mutations`, `changes`, or `targets` must contain at most 1 item to prevent overly broad proposals.
4. **Source Findings**: Must have at least 1 referenced source finding.
5. **Action-Specific Constraints**:
    - If not a `NO_DURABLE_LEARNING` action: requires `target_type`, `target`, `scope` (non-empty list), `boundary` (non-empty), and `validation` checklist.
    - `ADD` action requires `new` wording.
    - `DELETE` action requires `old` wording.
    - `REPLACE` action requires both `old` and `new` wording.
6. **Status Constraints**:
    - Proposal `action` describes the requested durable change (`ADD`, `DELETE`, `REPLACE`, `REJECT`, `NO_DURABLE_LEARNING`).
    - Proposal `status` describes the human lifecycle decision (`candidate`, `approved`, `rejected`, `applied`, `retired`).
    - Durable actions (`ADD`, `DELETE`, `REPLACE`) may be `candidate`, `approved`, `rejected`, `applied`, or `retired`.
    - `REJECT` and `NO_DURABLE_LEARNING` may only be `candidate` or `rejected`.
    - `APPROVED`, `APPLIED`, or `RETIRED` proposal requires `approved_by` and `approved_at` timestamp.
    - `REJECTED` proposal or a `REJECT` action requires a non-empty `reason`.
    - `RETIRED` proposal requires a non-empty `reason`. Retirement only applies to a previously `APPLIED` proposal whose durable change is now fully captured in its target skill/doc/memory home; `voku/agent-recall-compiler`'s `loadActiveGuidance()` only scans `proposals/approved/` and `proposals/applied/`, so a retired proposal stops being read into every future active recall guidance pool without needing any change in that package.
7. **Lifecycle Directory Check**: Proposal files under `proposals//` must embed the same `status` value.
8. **Scope Broader Check**: If proposal `scope` includes entries not present in the referenced findings, a `scope_justification` must be provided.
9. **Constraint Promotion Gates**: Constraint proposals require confirmed source findings, several independent findings or a critical-incident justification, explicit scope, explicit allowed boundaries, objective detectability, validation commands, declared false-positive risk, local example rule references where available, and engine-compatible target paths/commands.
10. **Learning Triage Gates**: When present, `learning_decision` must align with the proposal:

- `IGNORE` requires `NO_DURABLE_LEARNING`.
- `ADD_LEARNING_NOTE` preserves the raw learning without pretending it is ready for skill promotion.
- `UPDATE_SKILL` requires `target_type=skill`.
- `CREATE_SKILL` requires `ADD`, `target_type=skill`, `pattern_key`, `validation_case`, and an `overlap_check` with inspected skills and `max_overlap_percent
