Skip to content

feat(f1): /pos:audit-session — read-only advisory skill comparing policy.yaml vs .claude/logs/#25

Merged
javiAI merged 3 commits into
mainfrom
feat/f1-skill-audit-session
Apr 26, 2026
Merged

feat(f1): /pos:audit-session — read-only advisory skill comparing policy.yaml vs .claude/logs/#25
javiAI merged 3 commits into
mainfrom
feat/f1-skill-audit-session

Conversation

@javiAI

@javiAI javiAI commented Apr 26, 2026

Copy link
Copy Markdown
Owner

Summary

  • F1 abre Fase F tras cierre completo de Fase E (PR feat(e3b): skill-test-scaffold-audit-coverage — test quality advisory suite #24). Una skill nueva, /pos:audit-session, read-only advisory main-strict que cierra la capa 3 del determinismo declarado en docs/ARCHITECTURE.md § Determinismo: comparar lo que policy.yaml declara contra lo que .claude/logs/ realmente registra.
  • Tres superficies auditadas (decisión Fase -1 A1.a): (1) skills_allowedskills.jsonl invocations distintas (con pos: normalization); (2) lifecycle.<gate>.hooks_required<hook>.jsonl (existencia + nonempty); (3) audit.required_logs ↔ existencia + nonempty + mtime. Reporte estructurado por surface (3 secciones + summary line) con bullets <entry> — <type>: <reasoning>.
  • Pre-existing drift expected: hoy audit.required_logs declara hooks.jsonl pero los hooks logean a per-hook files (pre-branch-gate.jsonl, etc.). La skill reporta esto como Bucket 3 candidate y no auto-fixea — el usuario decide. Que el finding emerja en la primera invocación es evidencia de que el advisor funciona (decisión A4.a).
  • policy.yaml.skills_allowed 13 → 14 (audit-session añadido). stop-policy-check.py sigue en enforcement live, ahora con 14 skills aceptadas — sin cambio de código en el hook.
  • Ajustes obligatorios del usuario aplicados (3): (1) verificar shape real de policy.yaml antes del body; (2) recortar Bash(git log:*) de allowed-tools (final: 6 entries); (3) test del 30-day window valida declaración del body, no ejecución de date math.

Contrato locked por la suite (extiende E1..E3b)

  • Primitive frontmatter inmutable; sin skill.json; sin prefijo pos:; sin campos inventados.
  • audit-session es read-only advisory: nunca modifica policy.yaml, nunca rota/trunca/edita logs, nunca auto-fixea drift detectado. Tokens locked: advisory, read-only, does not modify, no modifica.
  • audit-session es main-strict: ausencia de subagent/code-architect/agent( enforce vivo. Si una rama futura propone delegation, abrir branch nueva con justificación (regla feat(c3): tests harness renderer — 13-file output per profile, deferred frameworks testeable #7 CLAUDE.md).
  • 30-day review window declarado como textual guidance para el lector humano — la skill no ejecuta date arithmetic, no filtra entries por timestamp, no podría aunque quisiera (allowed-tools subset estricto).
  • pos:<slug><slug> normalization assumption explicit en body (decisión consciente, no bug).
  • ALLOWED_SKILLS = 14 entries enforce vivo. Invocar una skill no listada sigue produciendo deny exit 2 (contrato D6 intacto).

Tests

  • .claude/skills/tests/test_skill_frontmatter.py — 22 parametrizados via ALLOWED_SKILLS 13→14 + 5 nuevos en TestAuditSessionBehavior (3 surfaces / advisory-only / main-strict no delegation / 30-day window declaration / prefix normalization assumption).
  • .claude/skills/tests/_allowed_skills.pyALLOWED_SKILLS 13 → 14; header docstring con línea F1.
  • hooks/tests/test_lib_policy.py::test_real_skills_allowed_populated_by_e3b rename a _by_f1; tupla 13 → 14.
  • hooks/tests/test_skills_log_contract.py::test_all_thirteen_e1_e3b_skills_end_to_end rename a test_all_fourteen_e1_e3b_f1_skills_end_to_end; allowlist + loop cubren las 14 skills.
  • 793 passed + 1 skipped (sin regresión D1..D6 + E1a..E3b). El skip es el D5 intencional TestIntegrationDiffUnavailable.

Test plan

  • RED-first: 16 failures iniciales (10 parametrizados + 5 behavior + 1 policy tuple).
  • GREEN: SKILL.md body satisface los 5 behavior tests literalmente; policy.yaml extendido 13→14; renames atómicos en log_contract + lib_policy.
  • Sin regresión: full hooks/ + skills/ suite verde tras docs-sync.
  • Docs-sync dentro del PR: ROADMAP § F1 detallado + Fase F abierta, HANDOFF §1+§9+§19, MASTER_PLAN § Rama F1 expandida + cierre ✅ PR pendiente, .claude/rules/skills-map.md fila audit-session populada.
  • docs/ARCHITECTURE.md no requerido (F1 no toca generator/ ni hooks/).
  • Pre-PR gate (D4 hook) aprueba este mismo PR — primer dogfooding D4 sobre Fase F.

🤖 Generated with Claude Code

Javier and others added 3 commits April 26, 2026 08:47
…it-session

Fase 0 kickoff + Fase 1 RED-first per CLAUDE.md regla #3 and .claude/rules/tests.md.

Plan ratificado por usuario: decisiones A1.a..A6.a + 3 ajustes obligatorios.
Scope: skill /pos:audit-session — read-only advisory main-strict que compara
3 superficies de policy.yaml contra .claude/logs/ reales:
  1. policy.yaml.skills_allowed vs skills.jsonl invocations.
  2. policy.yaml.lifecycle.*.hooks_required vs logs por hook
     (existencia + nonempty del archivo log esperado).
  3. policy.yaml.audit.required_logs vs existencia/edad/no-vacio.

RED state confirmado: 16 failures esperados.
  - 10 parametrizados [audit-session] en TestStructure / TestFrontmatter
    / TestBody. No existe .claude/skills/audit-session/SKILL.md.
  - 5 TestAuditSessionBehavior:
      * test_body_declares_three_audit_surfaces
      * test_body_declares_advisory_only
      * test_body_declares_main_strict_no_delegation
      * test_body_declares_30day_review_window
      * test_body_declares_prefix_normalization_assumption
  - 1 test_real_skills_allowed_populated_by_f1. policy.yaml todavia
    declara 13; ALLOWED_SKILLS ya crecio a 14.

Tests behavior siguen el patron de TestPatternAuditBehavior E3a — la
referencia mas cercana: read-only advisory main-strict.

Ajuste 3 del usuario aplicado: el test del 30-day window valida
DECLARACION del body, no ejecucion de date math.

Renames:
  - test_real_skills_allowed_populated_by_e3b -> _by_f1.
    Tupla 13 -> 14 via ALLOWED_SKILLS shared.
  - test_all_thirteen_e1_e3b_skills_end_to_end ->
    test_all_fourteen_e1_e3b_f1_skills_end_to_end.

GREEN phase proxima: crear SKILL.md + bump policy.yaml.skills_allowed.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
GREEN phase per CLAUDE.md regla #3 and .claude/rules/tests.md.
RED commit (5d6091d ancestor + RED) introduced 16 failures; this commit
turns all 16 green without touching any unrelated test.

Skill body (.claude/skills/audit-session/SKILL.md ~110 lines):
  - Frontmatter minimal canonical: name=audit-session, description starts
    "Use when ...", allowed-tools list of 6 entries (Glob, Grep, Read,
    Bash(find:*), Bash(wc:*), Bash(.claude/skills/_shared/log-invocation.sh:*)).
    No Bash(git log:*) per ajuste 2 del usuario.
  - Read-only advisory main-strict: scope explicito MAY/MUST NOT.
  - Three audit surfaces declared (Fase -1 decision A1.a):
      Bucket 1: skills_allowed vs skills.jsonl invocations.
      Bucket 2: lifecycle.*.hooks_required vs per-hook log files.
      Bucket 3: audit.required_logs vs file existence/nonempty/mtime.
  - 30-day review window declared as textual guidance (A2.a +
    ajuste 3 del usuario): the skill does NOT execute date math, the
    human applies the lens when reading the report.
  - Prefix normalization assumption (A3.a): pos:<slug> stripped before
    cross-comparing with policy.yaml.skills_allowed.
  - Pre-existing drift expected (A4.a): hooks.jsonl declared in
    audit.required_logs but no such file exists. Skill reports it as
    Bucket 3 candidate, does NOT auto-fix.
  - Report structured by surface (A5.a): three sections + summary line.
  - audit.session_audit.schedule (e.g. weekly) explicitly NOT enforced
    (A6.a): documental cadence, no cron/CI hook in F1.
  - Out of scope: external fork delegation (main-strict by design),
    cross-session aggregation, date arithmetic, mutating policy or logs.

Body satisfies all 5 TestAuditSessionBehavior tests literally:
  - skills_allowed + lifecycle + hooks_required + required_logs tokens.
  - "advisory"/"read-only"/"does not modify"/"no modifica" tokens.
  - No "subagent"/"code-architect"/"agent(" tokens (uses "fork" for
    external delegation refusal).
  - "30" + "day"/"review window" tokens.
  - "pos:" + "normaliz" tokens.

policy.yaml:
  - skills_allowed: 13 -> 14 entries (audit-session appended).
  - Comment line 268 updated: "E3b 13 skills -> F1 14 skills".

Test deltas (793 passed + 1 skipped, zero regression):
  - 10 parametrized [audit-session] in TestStructure / TestFrontmatter
    / TestBody pass.
  - 5 TestAuditSessionBehavior pass.
  - test_real_skills_allowed_populated_by_f1 passes (tuple is now 14).
  - test_all_fourteen_e1_e3b_f1_skills_end_to_end passes (logger ->
    Stop hook end-to-end with all 14 skills allowlisted).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase N+3 docs-sync per CLAUDE.md regla #2 (docs-sync within branch)
and pre-pr-gate.py canonical baseline (ROADMAP + HANDOFF mandatory)
plus conditional `.claude/rules/skills-map.md` for `skills/` paths.

ROADMAP.md:
  - Top table: Fase F status `pendiente` -> `1/4 (F1 ok, F2..F4 pending)`.
  - F1 row: status `pending` -> `done (PR pending)` with concrete scope.
  - New section "Progreso Fase F" with feat/f1 detail block:
    entregables, allowed-tools rationale, contract locked by suite,
    A1.a..A6.a decisions, 3 mandatory user adjustments, criterio salida.

HANDOFF.md:
  - Section 1 snapshot: Rama actual F1 (PR pendiente); next branch F2;
    F1 entregables one-liner.
  - Section 9 Proxima rama: F2 feat/f2-agents-subagents with scope
    (3 subagent definitions, naming-conflict question, agents_allowed
    evaluation).
  - New section 19 "Estado F1": full closure block parallel to E3a/E3b,
    with entregables + contract + 3 mandatory adjustments + YAML gotcha
    avoided + resultado (793 + 1 skip) + cross-references.

MASTER_PLAN.md Rama F1:
  - Replaced 1-line stub with full closing block: scope concrete (3
    surfaces), A1.a..A6.a decisions, 3 mandatory adjustments, contexto
    a leer, criterio de salida, carry-overs to F2..F4. Branch marker
    set to "PR pendiente".

.claude/rules/skills-map.md:
  - Audit + Release section: audit-session row populated with concrete
    contract (3 surfaces + main-strict + 30-day textual guidance + no
    auto-fix + allowed-tools list). Replaces the 1-line stub from F0.

Tests: 793 passed + 1 skipped (D5 intentional subprocess-no-cover).
Zero regression D1..D6 + E1a..E3b. Behavior contract for audit-session
locked across 5 tests.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 26, 2026 07:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new F1 skill to audit drift between declared policy and actual session logs, and wires it into the repo’s allowlist + contract tests/docs so it’s enforced and documented consistently with prior Phase E skills.

Changes:

  • Introduces /pos:audit-session skill definition as read-only advisory + main-strict, auditing three declared surfaces (skills_allowed, lifecycle.*.hooks_required, audit.required_logs) vs .claude/logs/.
  • Extends the enforced skill allowlist from 13 → 14 across policy.yaml and test fixtures/contracts.
  • Updates phase tracking docs (ROADMAP / MASTER_PLAN / HANDOFF) and the canonical skills map to reflect F1 completion and scope.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
policy.yaml Adds audit-session to skills_allowed and updates allowlist comment to reflect 14 skills.
hooks/tests/test_skills_log_contract.py Renames the end-to-end allowlist/log contract test and updates messaging for 14 skills.
hooks/tests/test_lib_policy.py Renames the “real skills_allowed populated” smoke test to F1 and updates docstring for 14-tuple expectation.
ROADMAP.md Marks Phase F as started with F1 completed and expands the F1 branch entry + narrative section.
MASTER_PLAN.md Expands F1 plan/closure details for audit-session, including surfaces and constraints.
HANDOFF.md Updates snapshot/next-branch guidance and adds a dedicated “Estado F1” section.
.claude/skills/tests/test_skill_frontmatter.py Adds behavior/contract tests for audit-session wording and constraints.
.claude/skills/tests/_allowed_skills.py Extends test allowlist to include audit-session.
.claude/skills/audit-session/SKILL.md Adds the new skill spec (scope, steps, framing, failure modes, out-of-scope).
.claude/rules/skills-map.md Adds the canonical skills-map row for audit-session (lifecycle/model/context/allowed-tools).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +65 to +69
- For each `lifecycle.<gate>.hooks_required` entry: does `.claude/logs/<hook-base>.jsonl` exist? Is it nonempty? Is its mtime within the 30-day review window?
- For each `<hook>.jsonl` present in `.claude/logs/`: is its base name in any `lifecycle.*.hooks_required`? If not → candidate `logging hook not declared in any lifecycle gate`.

**Bucket 3 — Required logs drift**:
- For each `audit.required_logs` entry: does the file exist in `.claude/logs/`? Is it nonempty? Is its mtime within the 30-day review window? (Mtime check is advisory only; report it, do not block on it.)

Copilot AI Apr 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These steps ask to check whether hooks/required logs’ file mtime is “within the 30-day review window”, which implies date-based logic. Earlier the skill says the 30-day window is only textual guidance and that it does not execute date math; consider clarifying that only file-level mtime heuristics are used (not per-entry timestamp arithmetic), or remove the mtime-within-window checks to avoid contradicting the scope section.

Suggested change
- For each `lifecycle.<gate>.hooks_required` entry: does `.claude/logs/<hook-base>.jsonl` exist? Is it nonempty? Is its mtime within the 30-day review window?
- For each `<hook>.jsonl` present in `.claude/logs/`: is its base name in any `lifecycle.*.hooks_required`? If not → candidate `logging hook not declared in any lifecycle gate`.
**Bucket 3 — Required logs drift**:
- For each `audit.required_logs` entry: does the file exist in `.claude/logs/`? Is it nonempty? Is its mtime within the 30-day review window? (Mtime check is advisory only; report it, do not block on it.)
- For each `lifecycle.<gate>.hooks_required` entry: does `.claude/logs/<hook-base>.jsonl` exist? Is it nonempty? Record/report its file mtime as an advisory freshness heuristic relative to the 30-day review window; do not perform exact date math or per-entry timestamp analysis.
- For each `<hook>.jsonl` present in `.claude/logs/`: is its base name in any `lifecycle.*.hooks_required`? If not → candidate `logging hook not declared in any lifecycle gate`.
**Bucket 3 — Required logs drift**:
- For each `audit.required_logs` entry: does the file exist in `.claude/logs/`? Is it nonempty? Record/report its file mtime as an advisory freshness heuristic relative to the 30-day review window; do not perform exact date math or per-entry timestamp analysis. (Mtime check is advisory only; report it, do not block on it.)

Copilot uses AI. Check for mistakes.

1. **Skills allowlist drift** — `policy.yaml.skills_allowed` (plain slugs) vs `.claude/logs/skills.jsonl` invocations. Detects: declared but never invoked (dead allowlist entry), invoked but not declared (would have been denied today by the Stop hook).
2. **Lifecycle hooks/log drift** — `policy.yaml.lifecycle.*.hooks_required` vs the per-hook log files in `.claude/logs/`. Detects: declared hook with no matching log file (hook never ran or never logged), declared hook with empty log (silently disabled), hooks logging that aren't declared in any lifecycle gate.
3. **Required logs drift** — `policy.yaml.audit.required_logs` vs file system reality. Detects: declared log file missing entirely, declared log file empty, declared log file older than the review window.

Copilot AI Apr 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section uses “Detects:” to describe findings. Given the advisory framing elsewhere in this repo for audit-style skills (“declares candidate signals”), consider rephrasing to avoid sounding like a definitive detector (e.g., “Declares candidate signals such as …”).

Suggested change
3. **Required logs drift**`policy.yaml.audit.required_logs` vs file system reality. Detects: declared log file missing entirely, declared log file empty, declared log file older than the review window.
3. **Required logs drift**`policy.yaml.audit.required_logs` vs file system reality. Declares candidate signals such as a declared log file missing entirely, a declared log file being empty, or a declared log file being older than the review window.

Copilot uses AI. Check for mistakes.
Comment on lines +792 to +794
assert any(tok in low for tok in advisory_tokens), (
"audit-session body must declare advisory/read-only scope."
)

Copilot AI Apr 26, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description says certain advisory/read-only tokens are “locked” (must appear literally), but this assertion only checks that any token exists. If the contract truly requires all tokens, tighten this to require each one (or add separate asserts) so wording drift can’t slip through.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skipping — the any(tok in low ...) is intentional. The body is bilingual (English 'does not modify' OR Spanish 'no modifica'), so requiring all-of would force redundant bilingual bodies. Pattern is consistent with other E3b behavior tests. The PR description wording was imprecise; the test asserts 'any of these advisory framings is present', not 'all four literal strings'.

@javiAI javiAI merged commit 50ca343 into main Apr 26, 2026
10 checks passed
@javiAI javiAI deleted the feat/f1-skill-audit-session branch April 26, 2026 07:48
javiAI added a commit that referenced this pull request Apr 26, 2026
* kickoff(f2): RED tests — agents/ + flips para pos-* namespace

Fase 0 + Fase 1 RED-first de feat/f2-agents-subagents.

Scope ratificado en Fase -1:
- 2 plugin subagents en agents/: pos-code-reviewer + pos-architect.
- auditor diferido (no consumer real hoy; regla #7 CLAUDE.md).
- Namespace pos-* para evitar colisión con built-in/user/project agents.
- NO tocar policy.yaml (sin agents_allowed; deferred sin consumer).
- NO tocar hooks/_lib/policy.py.
- NO extender audit-session.

Shape primitive (oficial Claude Code subagent):
- frontmatter: name + description + tools (comma-separated string) + model.
- body Markdown como system prompt.
- model: sonnet para ambos.
- Sin campos inventados.

Files RED en este commit:
- agents/tests/test_agent_frontmatter.py (NEW) — 24 RED tests:
  * Structure (2): file exists + parses
  * Frontmatter (14): keys subset, required, name match filename, namespace
    pos-*, description non-empty, tools comma-separated string, model valid
  * Body (2): substantive (>100 chars)
  * Capabilities (4): pos-code-reviewer menciona bug/security/scope/invariant;
    pos-architect menciona pattern/design/cross-file consistency.
- .claude/skills/tests/test_skill_frontmatter.py (MODIFIED):
  * TestPreCommitReviewBehavior::test_delegates_to_code_reviewer renombrado a
    test_delegates_to_pos_code_reviewer + asserta general-purpose fallback.
  * TestCompoundBehavior::test_body_declares_fallback renombrado a
    test_body_delegates_to_pos_architect_with_fallback (asserta
    pos-architect literal + general-purpose fallback).
  * pattern-audit + audit-session negation lists incluyen pos-architect /
    pos-code-reviewer (forward-compat: main-strict skills nunca deben
    referenciar plugin subagents).

Confirmado RED: 26 fail (24 agents + 2 skills flips) + 791 pass + 1 skip.
Regression intacta sobre E1a/E1b/E2a/E2b/E3a/E3b/F1.

Próximo: Fase 2 GREEN — escribir agents/pos-code-reviewer.md +
agents/pos-architect.md + actualizar bodies de pre-commit-review/SKILL.md +
compound/SKILL.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* feat(f2): GREEN — pos-code-reviewer + pos-architect plugin subagents

Fase 2 implementación que satisface los 24 RED tests + 2 skill flips.

agents/pos-code-reviewer.md — plugin subagent para branch-diff review.
Frontmatter primitive-correct (name + description + tools comma-separated +
model: sonnet, sin campos inventados). Body declara las 5 capacidades
explícitas que pre-commit-review delega: bugs / logic errors / security
vulnerabilities / scope adherence / invariant violations. Output contract:
findings agrupados por severidad (blocker/high/medium/nit), confidence-
filtered, file:line refs. Hard limits: no Edit, no Write, no PR, no
invocación de otras skills/subagents.

agents/pos-architect.md — plugin subagent para pattern extraction +
cross-file design. Frontmatter primitive-correct. Body declara 3
dimensiones: pattern extraction (≥2 repeticiones, regla #7), architectural
design (cohesión + tradeoffs), cross-file consistency. Output contract:
patterns en formato canónico (Name/Context/Signal/Rule/Examples/Rationale)
listo para que compound los folde en .claude/patterns/<slug>.md. Hard
limits: no refactor, no Edit, no overwriting de patterns existentes.

.claude/skills/pre-commit-review/SKILL.md — flip code-reviewer →
pos-code-reviewer (description + body + steps + failure modes). Fallback
a general-purpose se mantiene literal. subagent_type / agent tool refs
intactos.

.claude/skills/compound/SKILL.md — flip code-architect → pos-architect
(description + body + steps + failure modes). Fallback a general-purpose
intacto. Pattern format + STOP signal + writer-scoped strict intactos.

Resultado: 817 passed + 1 skipped (baseline 791 + 26 nuevos: 24 agents
contract + 2 skill flips). Zero regression sobre E1a/E1b/E2a/E2b/E3a/
E3b/F1.

Próximo: Fase N+1 simplify pre-PR + Fase N+3 docs-sync (ROADMAP/HANDOFF/
MASTER_PLAN/skills.md/skills-map.md/ARCHITECTURE.md).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(f2): sync ROADMAP + HANDOFF + MASTER_PLAN + rules/ for plugin subagents

Cierre de Fase N+3 docs-sync de F2: documenta los plugin subagents
`pos-code-reviewer` + `pos-architect` (entregados en commits previos
e63f438 RED + 2a5396b GREEN) en todas las superficies de docs del
meta-repo. Cero cambios de código en este commit — sólo prosa.

ROADMAP.md
  - Fila F status flippea a `🔄 (F1 ✅, F2 ✅, F3..F4 ⏳)`.
  - Fila F2 `⏳` → `✅ | — (PR pendiente)` con scope completo.
  - Sección `### feat/f2-agents-subagents — ✅ (PR pendiente)` nueva
    antes de "## Convenciones" — entregables, suite stats (817+1),
    contrato fijado, 6 decisiones Fase -1 ratificadas, exit criterion.

HANDOFF.md
  - §1 snapshot: rama actual F2 ✅ PR pendiente, anterior F1 ✅ #25,
    siguiente F3 — `feat/f3-selftest-end-to-end`.
  - §8 reframe: built-in subagents → plugin agents `pos-*` críticos
    (consumed by pre-commit-review + compound), built-in residuales
    sólo para branch-plan reads.
  - §9 Próxima rama: F2 → F3 (selftest end-to-end).
  - §20 Estado F2 NEW: entregables + contrato + decisiones + ajustes
    + resultado 817+1.

MASTER_PLAN.md
  - § Rama F2 expandida: scope 2 agents pos-*, archivos a crear/
    modificar, 6 decisiones cerradas, ajustes v1→v2 (recorte de 3→2
    + namespace + no policy), contexto a leer, criterio de salida,
    carry-overs F3/F4.

.claude/rules/skills.md
  - § Fork / delegación: precedentes flippean a `pos-code-reviewer`
    + `pos-architect` (post-F2) con disclaimer de fallback `general-
    purpose`. Plugin agent primitive box explícito (shape distinto
    al skill: `tools` comma-separated string vs YAML list `allowed-
    tools`). Forward-compat negation list extendida con `pos-*`.
  - Behavior tests row: refleja flips F2 + negation lists extendidas.

.claude/rules/skills-map.md
  - Filas `pre-commit-review` y `compound`: subagent_type flippea
    a `pos-code-reviewer` / `pos-architect` (post-F2), fallback
    `general-purpose` literal.
  - Sección "## Subagents del plugin (entregado en F2)" NEW: tabla
    con los 2 agents + contract tests + fallback + diferidos
    (`pos-auditor`, `agents_allowed`) + forward-compat negation.

Resultado: 817 passed + 1 skipped (sin cambios al code; suite
intacta). E1a..F1 + D1..D6 regression intacta. `docs/ARCHITECTURE.md`
NO modificado (decisión Fase -1 ratificada: F2 no toca `generator/`
ni `hooks/`; pre-pr-gate conditional no exige sync).

Próximo: simplify pre-PR + pre-commit-review (dogfooding F2 sobre
sí mismo: pre-commit-review delega a pos-code-reviewer) + gh pr
create.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* simplify(f2): fix stale framing in pre-commit-review delegation disclaimer

El disclaimer de Delegation rezaba "The string `pos-code-reviewer` here
reflects the Claude Code default shipped today" — wording correcto cuando
apuntaba a `code-reviewer` (built-in de Claude Code) pero stale post-flip
F2: `pos-code-reviewer` es plugin agent, no default de Claude Code.

Reescrito para reflejar la realidad post-F2: "The string `pos-code-reviewer`
is the plugin subagent shipped by `pos` in F2 (defined in
agents/pos-code-reviewer.md). It is hardcoded with a disclaimer: runtimes
that do not load plugin agents (or load them under different names) may
not expose it."

Sin cambios de comportamiento (la fallback rule a `general-purpose` queda
literal). Sin cambios al contrato de tests. Suite 817 passed + 1 skipped.

Writer-scoped strict: archivo dentro del diff `git diff --name-only main..HEAD`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(f2): address PR #26 review — required tools/model + ARCHITECTURE.md § 6

Atiende los 2 ajustes solicitados por el usuario sobre PR #26 (más un
fix trivial de un test name reference flaggeado por Copilot):

1. Hardening del contract de agent primitive
   `agents/tests/test_agent_frontmatter.py`:
   - `tools` y `model` movidos a `REQUIRED_FRONTMATTER_KEYS` (antes
     opcionales vía early-return — dejaba el contrato flojo para drift).
   - `test_tools_is_comma_separated_string` ahora valida tokens (split
     por `,`, asserts non-empty + sin whitespace en el nombre antes de
     `(...)` — antes un space-separated string pasaba el test).
   - `test_model_valid_if_present` → `test_model_valid` (sin early-return).
   - NUEVO `test_model_is_sonnet_for_f2` parametrizado por agent: lockea
     decisión Fase -1 (1) `model: sonnet`. Bumpear a opus/haiku exige
     rama nueva + ratificación.

2. `docs/ARCHITECTURE.md § 6 Agents` reescrita
   La sección era stale (listaba `code-reviewer` / `architect` /
   `auditor` sin namespace, usaba `allowed-tools:` que es shape de
   skill, no de agent). Ahora documenta:
   - top-level superficie `agents/<slug>.md` con primitive oficial
     (`name` / `description` / `tools` comma-separated / `model`);
   - tabla shape skill vs agent (divergencia esencial post-F2);
   - namespace `pos-*` obligatorio + test que lo lockea;
   - 2 agents entregados + diferidos (auditor + agents_allowed) +
     forward-compat negation.

3. Trivial: `HANDOFF.md` test name reference
   `test_name_is_pos_prefixed` → `test_name_uses_pos_namespace`
   (matcheaba el doc al test real; el doc estaba desincronizado).

Docs-sync sincronizado: ROADMAP + HANDOFF §20 + MASTER_PLAN § F2
ahora reportan 819 passed + 1 skipped (vs 817; +2 por el nuevo
`test_model_is_sonnet_for_f2` parametrizado por 2 agents) y
reconcilian la decisión (6) que ahora SÍ incluye
`docs/ARCHITECTURE.md § 6 Agents` (antes "no requerido" —
contradicción cerrada).

No cambios de scope: sin `agents_allowed`, sin `pos-auditor`, sin
modificar `policy.yaml`, sin tocar `audit-session`.

Suite: 819 passed + 1 skipped. Sin regresión D1..D6 / E1a..E3b / F1.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* docs(f2): reconcile count math + stale comment + diff syntax across docs

Five tweaks surfaced by Copilot's second pass on PR #26 (commit f230320):

1. .claude/skills/tests/test_skill_frontmatter.py:316 — stale comment said
   `code-reviewer` (built-in default) when the test now asserts
   `pos-code-reviewer` (plugin subagent shipped by F2). Reworded.
2. test_skill_frontmatter.py:351 + 419 — `main..HEAD` (two-dot, ancestor-only)
   in docstrings flipped to `main...HEAD` (three-dot, merge-base relative)
   matching what the skill bodies actually run.
3. HANDOFF.md:9 + §20:425 — count framing said "+24 contract + 2 skill flips"
   or "+28 nuevos". Suite delta is +26 net (793 → 819) from the new
   parametrized file (2 slugs × 13 methods). Behavior flips edit assertions
   in existing tests — they don't add count. Reframed everywhere.
4. ROADMAP.md:621 + MASTER_PLAN.md:694 + 722 — same reconciliation as (3).
5. MASTER_PLAN.md decision (6) line 706 + ROADMAP exit criteria 640 already
   updated in f230320 to include `docs/ARCHITECTURE.md § 6 Agents`; now
   the count math in the same paragraphs matches.

No code change. No test added or removed. Suite still 819 passed + 1 skipped.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Javier <javier.abril@glassnode.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants