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.

00[1 issues](https://github.com/voku/agent-learning/issues)[1 PRs](https://github.com/voku/agent-learning/pulls)PHPCI passing

Since Jun 9Pushed todayCompare

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

READMEChangelogDependenciesVersions (2)Used By (0)

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.

### 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.

### 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.
- Others (e.g., `schema_reference`, `runtime_observation`, `manual_verification`).

### 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`).
- [Action](src/Action.php): Enum representing actions (`NO_DURABLE_LEARNING`, `ADD`, `DELETE`, `REPLACE`, `REJECT`).

### 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.

### 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.
- [DecisionRecorder](src/DecisionRecorder.php): Validates log consistency of the decision history.

### Utilities &amp; Infrastructure

[](#utilities--infrastructure)

- [ConsolidationPromptBuilder](src/ConsolidationPromptBuilder.php): Assembles validated findings and rejected proposals history into a structured LLM consolidation prompt.
- [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 constructor; defaults to `'/^(ITPNG-\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**:
    - A `validated` finding status requires `validation_status=validated`.
    - 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**:
    - `APPROVED` or `APPLIED` proposal requires `approved_by` and `approved_at` timestamp.
    - `REJECTED` proposal or a `REJECT` action requires a non-empty `reason`.
7. **Scope Broader Check**: If proposal `scope` includes entries not present in the referenced findings, a `scope_justification` must be provided.

### Redaction Constraints

[](#redaction-constraints)

All keys and values are checked using [RedactionGuard](src/RedactionGuard.php) against secret assignment patterns. Any matches of standard credential assignments (e.g. `password`, `token`, `api_key`, `ms-Mcs-AdmPwd` patterns) throw a validation exception.

---

JSON Structure Formats
----------------------

[](#json-structure-formats)

### Example Finding

[](#example-finding)

```
{
  "id": "finding.2026-06-08.001",
  "task_id": "ITPNG-1234",
  "session": "session_abc123",
  "created_at": "2026-06-08T10:00:00+00:00",
  "created_by": "agent_alpha",
  "scope": [
    "lib/framework/forms"
  ],
  "observation": "FormElement validation fails when checking numeric bounds if string decimals are passed.",
  "evidence": [
    {
      "type": "file_reference",
      "path": "lib/framework/forms/FormElement.php",
      "line": 42
    },
    {
      "type": "test_result",
      "command": "make test_unit_file FILE=tests/FormElement_UnitCest.php",
      "summary": "Failed asserting that false is true on DecimalBound test"
    }
  ],
  "hypothesis": "String decimal inputs should be normalized to float/int before calling range checks in FormElement.",
  "validated_conclusion": "Normalizing value to float in range validation resolves bounds failures without side-effects.",
  "confidence": "high",
  "validation_status": "validated",
  "status": "validated",
  "sensitivity": "public"
}
```

### Example Proposal

[](#example-proposal)

```
{
  "id": "proposal.2026-06-08.001",
  "created_at": "2026-06-08T11:30:00+00:00",
  "action": "REPLACE",
  "target_type": "skill",
  "target": "itp-form-validation",
  "scope": [
    "lib/framework/forms"
  ],
  "source_findings": [
    "finding.2026-06-08.001"
  ],
  "old": "Validate range bounds directly using the raw inputs.",
  "new": "Ensure numeric inputs are cast/normalized to numeric values before validating range bounds.",
  "reason": "Prevents float/string type comparisons from failing bounds checks.",
  "boundary": "Only run numeric bounds normalization on Decimal and Float FormElement subclasses.",
  "validation": [
    "Ensure unit tests verify decimal string normalization."
  ],
  "status": "candidate",
  "proposed_by": "agent_alpha",
  "approved_by": null,
  "approved_at": null
}
```

---

Development &amp; Testing
-------------------------

[](#development--testing)

### Running Tests

[](#running-tests)

To run unit and integration tests for this package:

```
composer test
```

Or use the local `Makefile`:

```
make test
```

### Static Analysis

[](#static-analysis)

To run PHPStan checks on the package:

```
composer phpstan
```

Or use the local `Makefile`:

```
make phpstan
```

### CLI

[](#cli)

The Composer binary exposes the package workflow without requiring IT-Portal classes:

```
vendor/bin/agent-learning validate --root infra/doc/agent-learning
vendor/bin/agent-learning prepare --root infra/doc/agent-learning --ticket ITPNG-1234
vendor/bin/agent-learning proposal-validate --root infra/doc/agent-learning --proposal proposal.2026-06-08.001.json
```

`--root` may point either to the learning root itself or to a project root containing one of these directories:

- `infra/doc/agent-learning`
- `.agent-learning`
- `docs/agent-learning`
- `agent-learning`

Zero-byte `.json` files are treated as extraction placeholders and skipped. Non-empty finding, proposal, and history records are validated strictly.

###  Health Score

21

↑

LowBetter than 18% of packages

Maintenance65

Regular maintenance activity

Popularity0

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity13

Early-stage or recently created project

 Bus Factor1

Top contributor holds 50% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/6456fe693db197c458272cb758bf78958bc7d3e787ccd59db4bf3cf41654316a?d=identicon)[voku](/maintainers/voku)

---

Top Contributors

[![renovate[bot]](https://avatars.githubusercontent.com/in/2740?v=4)](https://github.com/renovate[bot] "renovate[bot] (2 commits)")[![voku](https://avatars.githubusercontent.com/u/264695?v=4)](https://github.com/voku "voku (2 commits)")

### Embed Badge

![Health badge](/badges/voku-agent-learning/health.svg)

```
[![Health](https://phpackages.com/badges/voku-agent-learning/health.svg)](https://phpackages.com/packages/voku-agent-learning)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
