feat(platformctl): generate module index and close catalog audits #836

Merged
pdurlej merged 1 commit from codex/issues-760-763-764-765-batch into main 2026-06-26 09:04:48 +02:00
Collaborator

Canary status: missing — fire canary via python -m platformctl.tools.run_review before merge

Summary

Implements platformctl index generate, records the catalog inventory evidence for #760/#765, and closes #764 as already satisfied by the current smoke contract on main. The generated modules/INDEX.yaml output removes the stale hand-maintained meta block whose total still said 84 while the repo has 88 module manifests.

Changes

  • Added control-plane/platformctl/module_index.py with deterministic module index generation from modules/*/module.yaml.
  • Added platformctl index generate [--json] to write modules/INDEX.yaml atomically when generated content differs.
  • Added module-index CLI/unit tests.
  • Generated modules/INDEX.yaml from manifests; all module entries are preserved, stale meta is removed.
  • Added state/reports/platform-catalog-inventory-2026-06-26.md with runbook, smoke, healthcheck, and index evidence.
  • Created follow-up #835 for the 34 docker-compose modules missing explicit health metadata.

Verification

  • PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests/test_module_index.py tests/test_smoke_contract.py control-plane/platformctl/tests/test_cross_refs.py
  • PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests — 790 passed
  • PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests/test_module_index.py tests/test_kan_runtime_contract.py tests/test_smoke_contract.py
  • PYTHONPATH=control-plane control-plane/.venv/bin/python -m platformctl.cli index generate --jsonmodule_count=88, changed=false after generation
  • PYTHONPATH=control-plane control-plane/.venv/bin/python -m platformctl.cli lint --cross-refs --json — exit 0, 0 errors, 5 known ADR sequence warnings
  • bash -n tests/smoke.sh
  • git diff --check

Test plan

  • Canary 3+3 fires and decision_packet.md is saved before merge.
  • After merge, rerun platformctl index generate --json to confirm changed=false on main.

Canary Context Pack

Product story

The module catalog should be reproducible by agents instead of hand-maintained. Agents should also be able to see whether the ready inventory issues produced real gaps without re-scanning the repo from scratch.

What changed

The PR adds the missing index generator, generates the current index, records inventory evidence, and creates a single healthcheck follow-up issue instead of many noisy tickets.

Why it changed

#763 said the repo already advertised platformctl index generate, but the command did not exist. #760/#765 were ready inventory issues. #764 was still open even though current tests/smoke.sh already contains the requested rewrite fixes and contract tests.

Files touched

  • control-plane/platformctl/module_index.py
  • control-plane/platformctl/cli.py
  • control-plane/platformctl/manifest.py
  • control-plane/platformctl/tests/test_module_index.py
  • control-plane/platformctl.egg-info/SOURCES.txt
  • modules/INDEX.yaml
  • state/reports/platform-catalog-inventory-2026-06-26.md

Relevant context

  • #760: runbook coverage inventory
  • #763: missing platformctl index generate
  • #764: smoke rewrite bugs from PR #40 canary
  • #765: healthcheck inventory
  • #835: follow-up for missing health metadata
  • contexts/module-catalog/MAP.md
  • contexts/observability/MAP.md

Runtime evidence

No runtime mutation and no live host access. Evidence is repo-local only.

Known constraints

The #763 issue mentioned control-plane/platformctl/validate.py, but that file does not exist on current main. The current manifest-loading helper is control-plane/platformctl/manifest.py, so this PR uses that instead.

Explicit out-of-scope

  • Adding healthchecks to the 34 missing modules; tracked in #835.
  • Runtime deploys, restarts, Docker changes, or live smoke against hosts.
  • Closing unrelated parked/proposed issues.

Requested decision

Approve after canary if reviewers agree the generated index structure should now be modules: only and the stale meta block should stay removed.

Merge blockers

  • platformctl index generate --json not idempotent after this PR.
  • Cross-ref lint reports errors.
  • Canary finds a real regression in CLI command wiring or generated index semantics.

Spec sources read

  • docs/forgejo-agent-operations.md — Forgejo write/identity protocol.
  • contexts/module-catalog/MAP.md — module catalog boundaries.
  • contexts/observability/MAP.md — smoke/health evidence boundaries.
  • Forgejo issues #760, #763, #764, #765 — task contracts.
  • modules/INDEX.yaml — index structure and generated output.
  • schema/module.schema.json — module fields and health schema.
  • control-plane/platformctl/cli.py — CLI wiring.
  • control-plane/platformctl/manifest.py — current manifest loader; used because issue-listed validate.py is absent.
  • tests/smoke.sh and tests/test_smoke_contract.py#764 evidence.
  • control-plane/platformctl/tests/test_cross_refs.py — existing runbook/index lint behavior.
  • control-plane/platformctl/tests/test_validate.py — manifest fixture shape.
  • Representative manifests: modules/n8n-worker/module.yaml, modules/honcho-api/module.yaml, modules/traefik/module.yaml.
  • modules/*/module.yaml health sections for #765 inventory only.

Closes #760
Closes #763
Closes #764
Closes #765

Canary status: missing — fire canary via `python -m platformctl.tools.run_review` before merge ## Summary Implements `platformctl index generate`, records the catalog inventory evidence for #760/#765, and closes #764 as already satisfied by the current smoke contract on main. The generated `modules/INDEX.yaml` output removes the stale hand-maintained `meta` block whose `total` still said 84 while the repo has 88 module manifests. ## Changes - Added `control-plane/platformctl/module_index.py` with deterministic module index generation from `modules/*/module.yaml`. - Added `platformctl index generate [--json]` to write `modules/INDEX.yaml` atomically when generated content differs. - Added module-index CLI/unit tests. - Generated `modules/INDEX.yaml` from manifests; all module entries are preserved, stale `meta` is removed. - Added `state/reports/platform-catalog-inventory-2026-06-26.md` with runbook, smoke, healthcheck, and index evidence. - Created follow-up #835 for the 34 docker-compose modules missing explicit health metadata. ## Verification - [x] `PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests/test_module_index.py tests/test_smoke_contract.py control-plane/platformctl/tests/test_cross_refs.py` - [x] `PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests` — 790 passed - [x] `PYTHONPATH=control-plane control-plane/.venv/bin/python -m pytest control-plane/platformctl/tests/test_module_index.py tests/test_kan_runtime_contract.py tests/test_smoke_contract.py` - [x] `PYTHONPATH=control-plane control-plane/.venv/bin/python -m platformctl.cli index generate --json` — `module_count=88`, `changed=false` after generation - [x] `PYTHONPATH=control-plane control-plane/.venv/bin/python -m platformctl.cli lint --cross-refs --json` — exit 0, 0 errors, 5 known ADR sequence warnings - [x] `bash -n tests/smoke.sh` - [x] `git diff --check` ## Test plan - [ ] Canary 3+3 fires and `decision_packet.md` is saved before merge. - [ ] After merge, rerun `platformctl index generate --json` to confirm `changed=false` on main. ## Canary Context Pack ### Product story The module catalog should be reproducible by agents instead of hand-maintained. Agents should also be able to see whether the ready inventory issues produced real gaps without re-scanning the repo from scratch. ### What changed The PR adds the missing index generator, generates the current index, records inventory evidence, and creates a single healthcheck follow-up issue instead of many noisy tickets. ### Why it changed #763 said the repo already advertised `platformctl index generate`, but the command did not exist. #760/#765 were ready inventory issues. #764 was still open even though current `tests/smoke.sh` already contains the requested rewrite fixes and contract tests. ### Files touched - `control-plane/platformctl/module_index.py` - `control-plane/platformctl/cli.py` - `control-plane/platformctl/manifest.py` - `control-plane/platformctl/tests/test_module_index.py` - `control-plane/platformctl.egg-info/SOURCES.txt` - `modules/INDEX.yaml` - `state/reports/platform-catalog-inventory-2026-06-26.md` ### Relevant context - #760: runbook coverage inventory - #763: missing `platformctl index generate` - #764: smoke rewrite bugs from PR #40 canary - #765: healthcheck inventory - #835: follow-up for missing health metadata - `contexts/module-catalog/MAP.md` - `contexts/observability/MAP.md` ### Runtime evidence No runtime mutation and no live host access. Evidence is repo-local only. ### Known constraints The #763 issue mentioned `control-plane/platformctl/validate.py`, but that file does not exist on current main. The current manifest-loading helper is `control-plane/platformctl/manifest.py`, so this PR uses that instead. ### Explicit out-of-scope - Adding healthchecks to the 34 missing modules; tracked in #835. - Runtime deploys, restarts, Docker changes, or live smoke against hosts. - Closing unrelated parked/proposed issues. ### Requested decision Approve after canary if reviewers agree the generated index structure should now be `modules:` only and the stale `meta` block should stay removed. ### Merge blockers - `platformctl index generate --json` not idempotent after this PR. - Cross-ref lint reports errors. - Canary finds a real regression in CLI command wiring or generated index semantics. ## Spec sources read - `docs/forgejo-agent-operations.md` — Forgejo write/identity protocol. - `contexts/module-catalog/MAP.md` — module catalog boundaries. - `contexts/observability/MAP.md` — smoke/health evidence boundaries. - Forgejo issues #760, #763, #764, #765 — task contracts. - `modules/INDEX.yaml` — index structure and generated output. - `schema/module.schema.json` — module fields and health schema. - `control-plane/platformctl/cli.py` — CLI wiring. - `control-plane/platformctl/manifest.py` — current manifest loader; used because issue-listed `validate.py` is absent. - `tests/smoke.sh` and `tests/test_smoke_contract.py` — #764 evidence. - `control-plane/platformctl/tests/test_cross_refs.py` — existing runbook/index lint behavior. - `control-plane/platformctl/tests/test_validate.py` — manifest fixture shape. - Representative manifests: `modules/n8n-worker/module.yaml`, `modules/honcho-api/module.yaml`, `modules/traefik/module.yaml`. - `modules/*/module.yaml` health sections for #765 inventory only. Closes #760 Closes #763 Closes #764 Closes #765
feat(platformctl): generate module index
All checks were successful
canary-required / collect-diff (pull_request) Successful in 4s
platformctl plan / auto-apply scope (pull_request) Successful in 18s
pyfallow / Pyfallow gate (control-plane) (pull_request) Successful in 15s
python-ci / Python 3.11 (pull_request) Successful in 40s
python-ci / Python 3.12 (pull_request) Successful in 41s
python-ci / Python 3.13 (pull_request) Successful in 41s
patchwarden-client-dry-run / collect-diff (pull_request) Successful in 4s
patchwarden-pr-sanity / collect-diff (pull_request) Successful in 4s
patchwarden-client-dry-run / dry-run (pull_request) Successful in 17s
canary-required / canary (pull_request) Successful in 17s
patchwarden-pr-sanity / sanity (pull_request) Successful in 59s
base-is-main / guard (pull_request) Successful in 1s
103484bca9
First-time contributor

Patchwarden PR sanity

Verdict: PASS WITH DEGRADED REVIEWER HEALTH - deterministic checks are clean, but this is not an approval signal.

Next step: Rerun PR sanity or inspect the degraded reviewer lane before unattended merge.

  • PR: 836
  • Commit: 103484bca9a4577f84a5d00323cd4392ec69ca71
  • Status: eligible_sanity_clean
  • Reviewer health: degraded
  • Security-sensitive label: missing
  • Authority: Patchwarden policy signal; branch protection and automerge controller remain merge authority.
  • Model mix: glm-5.2:cloud, deepseek-v4-pro:cloud, kimi-k2.7:cloud

What I checked

  • Changed files: 7
  • Deterministic blocker scan: clean
  • Model reviewer lanes: 3
  • Comment contract: this comment is updated in place via a hidden Patchwarden marker.

Approval Handoff

  • State: not_ready_degraded_reviewer_health
  • Action: rerun PR sanity or inspect the degraded reviewer lane before any unattended approval.
  • Boundary: branch protection and the automerge controller remain merge authority.

Required Fixes

No deterministic blockers.

Reviewer Details

Model reviewer lanes

global-glm / glm-5.2:cloud

  • Status: ok

  • Verdict: OK

  • low Manifest.area property can KeyError on manifests missing spec.classification.area

    • Evidence: control-plane/platformctl/manifest.py: areaproperty added asreturn self.data["spec"]["classification"]["area"]with no .get() fallback, mirroring the existingcriticality property. build_module_index in module_index.py calls manifes
    • Next: Confirm all 88 module manifests contain spec.classification.area (the inventory report implies they do). If any manifest omits it, generate_module_index will raise KeyError mid-generation and leave INDEX.yaml untouched due to atomic write — verify with a quick grep across modules/*/module.yaml befor

global-deepseek / deepseek-v4-pro:cloud

  • Status: ok
  • Verdict: OK
  • Findings: none

redteam / kimi-k2.7:cloud

  • Status: error
  • Verdict: -
  • Note: Ollama HTTP 404: {"error": "model 'kimi-k2.7:cloud' not found"}
  • Findings: none

Policy notes

  • Patchwarden PR sanity is the first merge-lane signal for this PR.
  • Models produce findings; Patchwarden/policy produces decisions.
  • Model findings alone do not fail the status check; they require human or agent disposition.
  • Formal approval is separate from this comment and requires clean reviewer health.
  • Automerge remains delegated to branch protection and the automerge pilot.
<!-- patchwarden-pr-sanity:pdurlej/platform:PR-836 --> <!-- patchwarden.pr_sanity.v1 status=eligible_sanity_clean model_health=degraded approval_handoff=not_ready_degraded_reviewer_health pr=836 sha=103484bca9a4577f84a5d00323cd4392ec69ca71 --> # Patchwarden PR sanity **Verdict:** PASS WITH DEGRADED REVIEWER HEALTH - deterministic checks are clean, but this is not an approval signal. **Next step:** Rerun PR sanity or inspect the degraded reviewer lane before unattended merge. - PR: `836` - Commit: `103484bca9a4577f84a5d00323cd4392ec69ca71` - Status: `eligible_sanity_clean` - Reviewer health: `degraded` - Security-sensitive label: `missing` - Authority: Patchwarden policy signal; branch protection and automerge controller remain merge authority. - Model mix: `glm-5.2:cloud`, `deepseek-v4-pro:cloud`, `kimi-k2.7:cloud` ## What I checked - Changed files: `7` - Deterministic blocker scan: `clean` - Model reviewer lanes: `3` - Comment contract: this comment is updated in place via a hidden Patchwarden marker. ## Approval Handoff - State: `not_ready_degraded_reviewer_health` - Action: rerun PR sanity or inspect the degraded reviewer lane before any unattended approval. - Boundary: branch protection and the automerge controller remain merge authority. ## Required Fixes No deterministic blockers. ## Reviewer Details <details> <summary>Model reviewer lanes</summary> ### `global-glm` / `glm-5.2:cloud` - Status: `ok` - Verdict: `OK` - **`low`** Manifest.area property can KeyError on manifests missing spec.classification.area - Evidence: `control-plane/platformctl/manifest.py: `area` property added as `return self.data["spec"]["classification"]["area"]` with no .get() fallback, mirroring the existing `criticality` property. build_module_index in module_index.py calls manifes` - Next: Confirm all 88 module manifests contain spec.classification.area (the inventory report implies they do). If any manifest omits it, generate_module_index will raise KeyError mid-generation and leave INDEX.yaml untouched due to atomic write — verify with a quick grep across modules/*/module.yaml befor ### `global-deepseek` / `deepseek-v4-pro:cloud` - Status: `ok` - Verdict: `OK` - Findings: none ### `redteam` / `kimi-k2.7:cloud` - Status: `error` - Verdict: `-` - Note: Ollama HTTP 404: {"error": "model 'kimi-k2.7:cloud' not found"} - Findings: none </details> ## Policy notes - Patchwarden PR sanity is the first merge-lane signal for this PR. - Models produce findings; Patchwarden/policy produces decisions. - Model findings alone do not fail the status check; they require human or agent disposition. - Formal approval is separate from this comment and requires clean reviewer health. - Automerge remains delegated to branch protection and the automerge pilot.
pdurlej deleted branch codex/issues-760-763-764-765-batch 2026-06-26 09:04:48 +02:00
Sign in to join this conversation.
No reviewers
No labels
W6d-automerge-calibration
agent/claude-code
agent/codex
agent/hermes
agent/iskra
agent/ollama
agent/patchwarden
automerge-candidate
class/security-sensitive
cutover-gate
dependency/blocked
dependency/blocks-others
dependency/cross-repo
dependency/needs-confirmation
domain:agents
domain:ci
domain:docs
domain:forgejo
domain:infra
domain:memory
domain:runtime
domain:signal
domain:ux
flow/architecture
flow/blocked
flow/deployed
flow/done
flow/implementation
flow/intake
flow/maintained
flow/observed
flow/ready
flow/refining
flow/retired
flow/review
iterating
judge/codex-candidate
judge/hermes-candidate
judge/low-confidence
judge/needs-refinement
judge/operator-needed
judge/p0
judge/p1
judge/p2
judge/p3
judge/park
judge/patchwarden-candidate
judge/stale-priority
kind/adr
kind/bug
kind/chore
kind/feature
kind/infra
kind/ops
kind/refactor
kind/research
large-impact
merge/auto
merge/manual
merge/manual-dependency-conflict
merge/manual-failing-tests
merge/manual-merge-conflict
merge/manual-missing-review
merge/manual-operator-preference
merge/manual-red-zone
merge/manual-security-sensitive
merge/manual-unclear-scope
merge/manual-unknown
meta
mode:operator-only
mode:patchwarden-iskra-approved
mode:safe-auto
needs-operator-decision
needs-triage
not-ready
observed/erroring
observed/needs-followup
observed/pending
observed/retire-candidate
observed/unused
observed/used
operator-emotional
owner-attention
phase/02
phase/03
priority:p0
priority:p1
priority:p2
priority:p3
proposed
ready-for-agent
ready-for-operator
recovery
review:claude-reviewed
review:codex-reviewed
review:dziadek-reviewed
review:needs-human
risk/exposure
risk/process
risk/product
risk/runtime
safety:external-write
safety:no-prod-mutation
safety:prod-impact
safety:secret-touch
size/large
size/medium
size/small
size/tiny
size/unknown
source/adr
source/agent-generated
source/manual
source/operator-chat
source/voice-note
status:blocked
status:codex-ready
status:merged:pending-evidence
status:needs-evidence
status:operator-needed
status:parked
tier/full
tier/lite
tier/stacked
tier:0-platform-substrate
tier:1-iskra-value-layer
tier:2-tools-products-modules
type:bug
type:chore
type:docs
type:feat
type:policy
type:research
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
pdurlej/platform!836
No description provided.