From a18d83f74aa8cf0119125793ff24e9f10ff1b630 Mon Sep 17 00:00:00 2001 From: tegwick Date: Mon, 28 Sep 2026 11:22:19 +0200 Subject: [PATCH] Prepare approved reporting repair and monthly review inputs Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e738-9e15-7600-87e6-90dec3a7beef --- SCOPE.md | 3 +- docs/ActivityCoreLoop.md | 36 +++++ .../2026-09-28-consumer-readiness.json | 31 ++++ .../2026-09-28-monthly-packet-fixture.json | 73 ++++++++++ .../2026-09-28-reporting-diagnosis.json | 22 +++ .../evidence/2026-09-28-reporting-repair.json | 25 ++++ .../2026-09-28-reporting-schedules.json | 134 ++++++++++++++++++ feedback/ConsumerIntegration.md | 43 ++++++ feedback/monthly-review-input.json | 16 +++ integrations/activity-core/Dockerfile | 6 + integrations/activity-core/README.md | 54 +++++++ .../activity-core/monthly-review.patch | 77 ++++++++++ integrations/activity-core/source.json | 7 + .../test_frontend_monthly_review.py | 87 ++++++++++++ integrations/activity-core/worker-image.patch | 22 +++ .../FEP-WP-0008-use-driven-improvement.md | 28 ++++ 16 files changed, 663 insertions(+), 1 deletion(-) create mode 100644 docs/evidence/2026-09-28-consumer-readiness.json create mode 100644 docs/evidence/2026-09-28-monthly-packet-fixture.json create mode 100644 docs/evidence/2026-09-28-reporting-diagnosis.json create mode 100644 docs/evidence/2026-09-28-reporting-repair.json create mode 100644 docs/evidence/2026-09-28-reporting-schedules.json create mode 100644 feedback/ConsumerIntegration.md create mode 100644 feedback/monthly-review-input.json create mode 100644 integrations/activity-core/Dockerfile create mode 100644 integrations/activity-core/README.md create mode 100644 integrations/activity-core/monthly-review.patch create mode 100644 integrations/activity-core/source.json create mode 100644 integrations/activity-core/test_frontend_monthly_review.py create mode 100644 integrations/activity-core/worker-image.patch diff --git a/SCOPE.md b/SCOPE.md index 0e2a90f..d28f70f 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -102,7 +102,8 @@ qualified reference use to evidence-bearing consumer receipts and bounded autono improvement. It owns discovery, instrumentation and execution integration; monthly human review owns operating-policy decisions. The capability entry is prepared; automatic collection and three activity-core reporting schedules passed scheduled -smoke checks; the first natural daily receipt remains unverified. +smoke checks; the first natural daily run failed after a worker image change removed +the domain resolver. A tested repair is staged pending release authorization. Hosted consumer integration and admitted pattern-editing execution remain blocked; there are no enrolled consumers yet. This operational loop can improve draft guidance without claiming M1/M2/M3 or diff --git a/docs/ActivityCoreLoop.md b/docs/ActivityCoreLoop.md index c42b872..094047a 100644 --- a/docs/ActivityCoreLoop.md +++ b/docs/ActivityCoreLoop.md @@ -1,5 +1,10 @@ # Activity-core receipt loop +Current diagnosis (2026-09-28): the first natural daily run fired but failed because +the replacement worker image lacks the domain resolver. A tested repair image is +published and awaits the scoped attended-release exception; prior smoke success +is historical. See [repair evidence](evidence/2026-09-28-reporting-repair.json). + FEP-WP-0008 owns this integration. The initial delivery is deterministic collection and reporting. Automatic investigation and publication are a separate, outstanding execution dependency; a weekly report is not evidence of an improvement cycle. @@ -134,3 +139,34 @@ September 27 14:07Z smoke receipt. See [recheck](evidence/2026-09-28-loop-rechec Enabled schedules and prior smoke success do not prove this recurring execution. WP-0008 T03 retains cadence/sink diagnosis; no outage cause or live fix is claimed. The roster remains empty and mutation execution remains unadmitted. + + +## Diagnosed failure and prepared repair — 2026-09-28 + +Temporal fired the daily definition at 00:00Z. Worker run +`01a0e54f-c690-7caa-bae6-81cd5ed32416` failed with required context source +`frontend-patterns` not registered. Source `428f2d7` changed the worker from the +frontend overlay to the grant-aware API image; the running image has neither the +resolver module nor its registration. ArgoCD and pod readiness were healthy, so +those probes did not establish domain functionality. + +[Diagnosis](evidence/2026-09-28-reporting-diagnosis.json), +[schedule readback](evidence/2026-09-28-reporting-schedules.json), and +[repair contract](../integrations/activity-core/README.md) pin the evidence. +The prepared overlay keeps the current grant-aware base and changes only the +domain resolver and its registration. Hash comparison preserves all other Python +source and the grant identity. The candidate also adds monthly owner-snapshot +health, decisions and measured research effort with unknown counts; it never grants +execution authority. Missing review inputs degrade the report visibly. + +58 focused tests and 17 GitOps tests pass. Server dry-run passes for the same nine +resources; the actual resource diff is only the worker image. The published digest +is `afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437`. +The October 1 built-image fixture is 1,699 characters and contains no consumers, +unknown eligible-task denominator and unknown cost observations. This is fixture +proof, not an actual October run. Production promotion remains separately gated. + +Hosted discovery is still unregistered (404) and its routed write credential is +unavailable to the current operator session. Public source publication passed. +The [consumer hook](../feedback/ConsumerIntegration.md) is prepared, but no real +consumer was fabricated or enrolled. These obligations remain WP-0008 T01/T02. diff --git a/docs/evidence/2026-09-28-consumer-readiness.json b/docs/evidence/2026-09-28-consumer-readiness.json new file mode 100644 index 0000000..7e2720c --- /dev/null +++ b/docs/evidence/2026-09-28-consumer-readiness.json @@ -0,0 +1,31 @@ +{ + "checked_at": "2026-09-28T09:21:05.990563+00:00", + "public_index_url": "https://forgejo.coulomb.social/coulomb/frontend-patterns/raw/branch/main/registry/indexes/capabilities.yaml", + "public_index_http_status": 200, + "hosted_registration_http_status": 404, + "credential_route": "reuse-surface-hub-write-token", + "credential_owner": "railiance-platform / OpenBao", + "registration_status": "blocked: routed credential unavailable to current operator session", + "credential_output_retained": false, + "consumer_roster_count": 0, + "candidate_scan": "Local workplan titles for frontend/UI/navigation/dashboard/portal/editor/wizard/cockpit across active/ready/blocked/proposed plans. A title scan is not an exhaustive task-level eligibility review.", + "candidates": [ + { + "repo": "hub-core", + "workplan": "HUB-WP-0006", + "status": "blocked", + "reason_not_enrolled": "No active consumer decision/outcome inspected or authorized by this session." + }, + { + "repo": "rapp-openbao", + "workplan": "RAPP-OPENBAO-WP-0002", + "status": "blocked", + "reason_not_enrolled": "Operator access policy, not a qualified frontend architecture consumption task." + } + ], + "finished_examples_not_reopened": [ + "vergabe-teilnahme VT-WP-0003/0004", + "state-hub STATE-WP-0048" + ], + "consumer_instruction_ref": "feedback/ConsumerIntegration.md" +} diff --git a/docs/evidence/2026-09-28-monthly-packet-fixture.json b/docs/evidence/2026-09-28-monthly-packet-fixture.json new file mode 100644 index 0000000..88ad428 --- /dev/null +++ b/docs/evidence/2026-09-28-monthly-packet-fixture.json @@ -0,0 +1,73 @@ +{ + "basis": "built-image fixture; future October 1 clock; no production execution", + "bytes": 1699, + "report": { + "repo": "frontend-patterns", + "mode": "monthly", + "generated_at": "2026-10-01T07:00:00+00:00", + "status": "no_consumers", + "execution_ready": false, + "model_calls": 0, + "eligible_tasks": null, + "instrumented_repositories": 0, + "source_revisions": [ + "frontend-patterns@aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + ], + "receipt_events": 0, + "duplicates": 0, + "real_uses": 0, + "synthetic_uses": 0, + "outcomes": {}, + "decisions": {}, + "signals": [], + "errors": {}, + "limits": [ + "Producer outcomes are not independently verified.", + "No admitted budget-enforced repository executor; automatic edits disabled.", + "Missing consumer instrumentation means coverage is unknown." + ], + "workplan": "FEP-WP-0008", + "executor_dependency": "GLAS-WP-0012 / HFACT-WP-0001", + "window": { + "start": "2026-09-01T00:00:00+02:00", + "end_exclusive": "2026-10-01T00:00:00+02:00" + }, + "review": { + "basis": "owner snapshot; not live attestation", + "as_of": "2026-09-28T09:15:00.370856+00:00", + "stale": false, + "health": { + "schedule": "daily fired; collection failed", + "collection": "deployed resolver missing", + "verification": "no consumer outcomes verified", + "publication": "0.1 pinned; repair not deployed", + "rollback": "automatic proof pending", + "executor": "not admitted" + }, + "evidence_ref": "docs/evidence/2026-09-28-reporting-diagnosis.json", + "decisions": [], + "default": "Retain current policy/budgets; no new authority or maturity claim.", + "research_cycles": 18, + "measured_effort": { + "research_minutes": { + "known": 43.011, + "unknown_cycles": 11 + }, + "execution_minutes": { + "known": 3.222, + "unknown_cycles": 11 + }, + "reported_tokens": { + "known": 0, + "unknown_cycles": 18 + }, + "cost_usd": { + "known": 0, + "unknown_cycles": 18 + } + } + }, + "unselected_signals": 0, + "summary": "Frontend patterns monthly: no_consumers; 0 real uses, 0 unverified outcome signals. Automatic edits disabled." + } +} diff --git a/docs/evidence/2026-09-28-reporting-diagnosis.json b/docs/evidence/2026-09-28-reporting-diagnosis.json new file mode 100644 index 0000000..8a58892 --- /dev/null +++ b/docs/evidence/2026-09-28-reporting-diagnosis.json @@ -0,0 +1,22 @@ +{ + "checked_at": "2026-09-28T09:15:00.370856+00:00", + "workplan": "FEP-WP-0008", + "deployed_source_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f", + "worker_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd", + "pod_created_at": "2026-09-27T19:58:36Z", + "worker_ready": true, + "argo_health": "Healthy", + "daily_schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e", + "failed_workflow_id": "activity-99f02c4c-161e-515d-926d-9e5d11d8411e:${firstScheduledTime}-2026-09-28T00:00:00Z", + "failed_workflow_run_id": "01a0e54f-c690-7caa-bae6-81cd5ed32416", + "error": [ + "temporalio.exceptions.ApplicationError: Required context source type 'frontend-patterns' is not registered" + ], + "worker_module_inspection": { + "frontend_patterns_module_exists": false, + "package_init_imports_frontend_patterns": false + }, + "diagnosis": "Source 428f2d7 changed worker from frontend overlay 77244c3 to grant-aware image 713bddad; resolver absent. Schedule fired, required-context failure stopped collection. Healthy pod/Argo status did not cover domain functionality.", + "repair": "Overlay resolver onto current grant-aware image; do not roll back to the older image that lacks grants.", + "production_mutation": false +} diff --git a/docs/evidence/2026-09-28-reporting-repair.json b/docs/evidence/2026-09-28-reporting-repair.json new file mode 100644 index 0000000..df85ed1 --- /dev/null +++ b/docs/evidence/2026-09-28-reporting-repair.json @@ -0,0 +1,25 @@ +{ + "status": "approved_candidate_not_yet_deployed", + "base_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd", + "candidate_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437", + "upstream_source_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f", + "tests_passed": 58, + "changed_python_files": [ + "context_resolvers/__init__.py", + "context_resolvers/frontend_patterns.py" + ], + "all_other_python_source_hashes_unchanged": true, + "grant_identity_preserved": true, + "registry_added": [ + "frontend-patterns" + ], + "monthly_fixture_ref": "docs/evidence/2026-09-28-monthly-packet-fixture.json", + "production_mutation": false, + "deployment_gate": "Existing 24-hour healthy observation invalidated by required-context failure; attended exact repair exception or admitted owner release lane required.", + "gitops_tests_passed": 17, + "server_dry_run": "passed; nine existing managed resources", + "registry_digest_readback": true, + "worker_image_patch": "integrations/activity-core/worker-image.patch", + "rollback_revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f", + "authorization_decision": "abdea390-1039-4da1-b129-33aad00b4396" +} diff --git a/docs/evidence/2026-09-28-reporting-schedules.json b/docs/evidence/2026-09-28-reporting-schedules.json new file mode 100644 index 0000000..322f4f5 --- /dev/null +++ b/docs/evidence/2026-09-28-reporting-schedules.json @@ -0,0 +1,134 @@ +[ + { + "id": "99f02c4c-161e-515d-926d-9e5d11d8411e", + "name": "Frontend Patterns Daily Review", + "enabled": true, + "trigger_type": "cron", + "schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e", + "definition_source": "database", + "sources": [ + "database", + "temporal" + ], + "trigger": { + "cron_expression": "0 2 * * *", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + }, + "cron_expression": "0 2 * * *", + "at": null, + "timezone": "Europe/Berlin", + "misfire_policy": "catchup_latest", + "catchup_window_seconds": null, + "jitter_seconds": 0, + "temporal": { + "status": "active", + "schedule_id": "activity-schedule-99f02c4c-161e-515d-926d-9e5d11d8411e", + "paused": false, + "last_fired_at": "2026-09-28T00:00:00+00:00", + "missed_catchup_window": 0 + }, + "drift_hints": [], + "version": 1, + "created_at": "2026-09-27T11:23:29.549570+00:00", + "updated_at": "2026-09-27T11:23:29.549570+00:00", + "side_effect": false, + "trigger_config_public": { + "cron_expression": "0 2 * * *", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + } + }, + { + "id": "92e514a6-aeb8-5e22-9292-c62dd26dd757", + "name": "Frontend Patterns Monthly Review", + "enabled": true, + "trigger_type": "cron", + "schedule_id": "activity-schedule-92e514a6-aeb8-5e22-9292-c62dd26dd757", + "definition_source": "database", + "sources": [ + "database", + "temporal" + ], + "trigger": { + "cron_expression": "0 9 1 * *", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + }, + "cron_expression": "0 9 1 * *", + "at": null, + "timezone": "Europe/Berlin", + "misfire_policy": "catchup_latest", + "catchup_window_seconds": null, + "jitter_seconds": 0, + "temporal": { + "status": "active", + "schedule_id": "activity-schedule-92e514a6-aeb8-5e22-9292-c62dd26dd757", + "paused": false, + "last_fired_at": null, + "missed_catchup_window": 0 + }, + "drift_hints": [], + "version": 1, + "created_at": "2026-09-27T11:23:29.549570+00:00", + "updated_at": "2026-09-27T11:23:29.549570+00:00", + "side_effect": false, + "trigger_config_public": { + "cron_expression": "0 9 1 * *", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + } + }, + { + "id": "562005f8-ef43-5a9d-83e2-f09e00e62b81", + "name": "Frontend Patterns Weekly Review", + "enabled": true, + "trigger_type": "cron", + "schedule_id": "activity-schedule-562005f8-ef43-5a9d-83e2-f09e00e62b81", + "definition_source": "database", + "sources": [ + "database", + "temporal" + ], + "trigger": { + "cron_expression": "0 3 * * 2", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + }, + "cron_expression": "0 3 * * 2", + "at": null, + "timezone": "Europe/Berlin", + "misfire_policy": "catchup_latest", + "catchup_window_seconds": null, + "jitter_seconds": 0, + "temporal": { + "status": "active", + "schedule_id": "activity-schedule-562005f8-ef43-5a9d-83e2-f09e00e62b81", + "paused": false, + "last_fired_at": null, + "missed_catchup_window": 0 + }, + "drift_hints": [], + "version": 1, + "created_at": "2026-09-27T11:23:29.549570+00:00", + "updated_at": "2026-09-27T11:23:29.549570+00:00", + "side_effect": false, + "trigger_config_public": { + "cron_expression": "0 3 * * 2", + "trigger_type": "cron", + "misfire_policy": "catchup_latest", + "jitter_seconds": 0, + "timezone": "Europe/Berlin" + } + } +] diff --git a/feedback/ConsumerIntegration.md b/feedback/ConsumerIntegration.md new file mode 100644 index 0000000..d21ee67 --- /dev/null +++ b/feedback/ConsumerIntegration.md @@ -0,0 +1,43 @@ +# First consumer integration + +FEP-WP-0008 T01/T02 owns this bounded handoff; no consumer is enrolled by this file. +Use the common instruction owner for the selected repository. Do not install a fleet +mandate, reopen a finished task, or invent product work to manufacture adoption. + +## Eligibility + +A real, open frontend task must need a decision about shared edits, offline recovery, +navigation/rendering, interaction or feature boundaries. The consumer keeps its own +implementation authority. A deployment repair or documentation-only inspection of +this pattern repository is not an external frontend use. Unsupported contexts should +produce an explicit no-match decision, not a forced pattern selection. + +## Short planning and closeout instruction + +> For eligible frontend architecture work, query +> `capability.infotech.frontend-pattern-language` through hosted reuse-surface. +> Read START.md and the full applicable contracts in the pinned reference release. +> Record its version, packaging revision and manifest digest with selected/rejected +> CAND IDs, task constraints, alternatives and unmet conditions in the task's decision +> note. At closeout, emit an immutable PatternUseReceipt event and index it with its +> SHA-256; unknown outcome is valid. At the first linked test/review/incident, append +> an outcome event with the preceding event digest. Never edit the earlier receipt, +> invent helpfulness, or treat model judgment as observed user benefit. + +The [receipt template](../templates/PatternUseReceipt.yaml) and +[index/enrollment contract](README.md) define exact fields. Pin the packaging +revision in [releases.json](../reference/releases.json), not the latest research +HEAD. Read [unsupported contexts](../reference/0.1/README.md) before selecting. + +## Acceptance + +Before adding an actual consumer to `sources.json`, verify its published receipt +index and immutable event hashes at a concrete revision. Check the source through +activity-core's existing validator/collector. Keep a decision-only unknown outcome +unknown until a linked outcome arrives. Fixture positive/negative paths test the +collector; they do not satisfy real-use acceptance. Enrollment is limited to the +existing allowlist and collection bounds in the runbook. + +Hosted registration currently needs the routed OpenBao write credential. Public +index publication is verified, but lookup/registration and a real consumer receipt +must be evidenced separately. Do not infer discovery success from this instruction. diff --git a/feedback/monthly-review-input.json b/feedback/monthly-review-input.json new file mode 100644 index 0000000..bd96f26 --- /dev/null +++ b/feedback/monthly-review-input.json @@ -0,0 +1,16 @@ +{ + "schema_version": 1, + "as_of": "2026-09-28T09:15:00.370856+00:00", + "health": { + "schedule": "daily fired; collection failed", + "collection": "deployed resolver missing", + "verification": "no consumer outcomes verified", + "publication": "0.1 pinned; repair not deployed", + "rollback": "automatic proof pending", + "executor": "not admitted" + }, + "evidence_ref": "docs/evidence/2026-09-28-reporting-diagnosis.json", + "decisions": [], + "default": "Retain current policy and budgets; no maturity promotion or execution grant.", + "note": "Owner-maintained snapshot, not live health attestation. Refresh after repair; missing evidence stays unknown." +} diff --git a/integrations/activity-core/Dockerfile b/integrations/activity-core/Dockerfile new file mode 100644 index 0000000..e7a25fa --- /dev/null +++ b/integrations/activity-core/Dockerfile @@ -0,0 +1,6 @@ +# Preserve the deployed grant-aware runtime; restore only the domain resolver. +FROM forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd +COPY src/activity_core/context_resolvers/frontend_patterns.py /app/src/activity_core/context_resolvers/frontend_patterns.py +RUN printf '\nfrom activity_core.context_resolvers import frontend_patterns # noqa: F401\n' >> /app/src/activity_core/context_resolvers/__init__.py +# Image construction must prove both features coexist, without network or secrets. +RUN python -c "import activity_core.context_resolvers; from activity_core.context_resolvers.base import CONTEXT_RESOLVER_REGISTRY; from activity_core.repository_grant import RepositoryGrant; assert 'frontend-patterns' in CONTEXT_RESOLVER_REGISTRY; assert RepositoryGrant.model_validate({'version':'1','allowed_paths':['docs/'],'commit_count':{'min':1,'max':1},'publish':False}).payload()['publish'] is False" diff --git a/integrations/activity-core/README.md b/integrations/activity-core/README.md new file mode 100644 index 0000000..ac28fde --- /dev/null +++ b/integrations/activity-core/README.md @@ -0,0 +1,54 @@ +# Bounded reporting repair for Activity Core + +Owner task: FEP-WP-0008 T03, alongside existing ACTIVITY-WP-0041. No new workplan. + +The September 27 grant-aware image promotion removed the frontend resolver. Keep +that grant-aware base. This overlay changes only the resolver module and its package +registration; it does not roll back grants, change schedules, or admit a mutation +executor. [Diagnosis](../../docs/evidence/2026-09-28-reporting-diagnosis.json). + +`source.json` pins the upstream source revision and resolver hashes. Reproduce with +an isolated checkout of that exact activity-core revision: + +```sh +git apply /home/worsch/frontend-patterns/integrations/activity-core/monthly-review.patch +cp /home/worsch/frontend-patterns/integrations/activity-core/Dockerfile Dockerfile.reporting-repair +cp /home/worsch/frontend-patterns/integrations/activity-core/test_frontend_monthly_review.py tests/ +PYTHONDONTWRITEBYTECODE=1 .venv/bin/python -m pytest -q -p no:cacheprovider \ + tests/test_frontend_patterns.py tests/test_frontend_monthly_review.py \ + tests/test_repository_grant.py tests/test_resolve_context_binding.py +docker build -f Dockerfile.reporting-repair -t activity-core:fep-reporting-repair-20260928 . +``` + +The isolated checkout needs the owner's existing locked development environment. +The Docker build itself needs no new dependency installation: it extends the pinned +runtime and proves resolver registration plus typed grant support during construction. +The review compares all Python source hashes against the base, not only image labels. + +The monthly extension reads this repository's `feedback/monthly-review-input.json`, +its cited evidence and learning ledger at the same resolved Git revision. It reports +six health dimensions as an **owner snapshot**, dated and stale after seven days; +these fields cannot grant execution authority. Measured research/execution/token/cost +sums include unknown-cycle counts and only the reporting month. Costs are not inferred +from tokens. At most three bounded decision proposals carry no-response defaults. +Missing input/evidence or invalid effort yields a degraded packet while retaining +receipt totals. The existing 3,900-character digest bound still applies. Daily and +weekly collection remain unchanged. It is not an independent live health observer. + +The [October fixture](../../docs/evidence/2026-09-28-monthly-packet-fixture.json) +uses the built image with network disabled and a future clock. It is not an October +production run or completed monthly review. The first actual packet is due October 1. + +Deploy only this worker's exact reviewed digest through the existing GitOps source +and ArgoCD path; preserve the API and event-router images and all non-image fields. +The current deployment is `428f2d7`, grant-aware base `713bddad…`; use that exact +revision as the rollback target, acknowledging that rollback restores broken domain +reporting. A rollback must preserve repository grants. Verify resolver and grant +hashes, all three definitions, a report-only scheduled smoke and monthly sink after +rollout. Do not retry the failed historical run as though it had succeeded naturally. + +The owner's [release runbook](../../../activity-core/docs/gitops-release.md) requires +24 healthy hours and authenticated release authority. The domain failure invalidates +continuous-health claims; no admitted routine identity exists. An exact attended repair +exception is required before production promotion. Staging this artifact is not that +exception. No access/budget/policy expansion is part of the repair. diff --git a/integrations/activity-core/monthly-review.patch b/integrations/activity-core/monthly-review.patch new file mode 100644 index 0000000..522cb08 --- /dev/null +++ b/integrations/activity-core/monthly-review.patch @@ -0,0 +1,77 @@ +--- a/src/activity_core/context_resolvers/frontend_patterns.py ++++ b/src/activity_core/context_resolvers/frontend_patterns.py +@@ -10,6 +10,7 @@ + from datetime import datetime, timezone + import hashlib + import json ++import math + from pathlib import PurePosixPath + import re + import time +@@ -149,6 +150,44 @@ + return latest + + ++def monthly_review(root_sha: str, now: datetime, start: datetime, end: datetime) -> dict: ++ """Bounded, source-pinned owner snapshot and measured research totals. ++ ++ This is review input, never authority or a live health attestation. ++ Missing/invalid input degrades the monthly packet while preserving receipts. ++ """ ++ data = json.loads(raw("frontend-patterns", root_sha, "feedback/monthly-review-input.json")) ++ require(data["schema_version"] == 1, "invalid_monthly_input") ++ stamp = datetime.fromisoformat(data["as_of"].replace("Z", "+00:00")) ++ require(stamp.tzinfo is not None and stamp <= now, "invalid_monthly_date") ++ health = data["health"] ++ keys = {"schedule", "collection", "verification", "publication", "rollback", "executor"} ++ require(isinstance(health, dict) and set(health) == keys, "invalid_monthly_health") ++ require(all(isinstance(v, str) and 0 < len(v) <= 80 for v in health.values()), "invalid_monthly_health") ++ require(path_ok(data["evidence_ref"]), "invalid_monthly_evidence") ++ # The cited file must exist at this same source revision. ++ raw("frontend-patterns", root_sha, data["evidence_ref"]) ++ decisions = data["decisions"] ++ require(isinstance(decisions, list) and len(decisions) <= 3, "invalid_monthly_decisions") ++ for decision in decisions: ++ require(isinstance(decision, dict) and set(decision) == {"question", "recommendation", "default"}, "invalid_monthly_decision") ++ require(all(isinstance(v, str) and 0 < len(v) <= 100 for v in decision.values()), "invalid_monthly_decision") ++ ledger = json.loads(raw("frontend-patterns", root_sha, "research/evolution/ledger.json")) ++ events = ledger["events"] ++ require(isinstance(events, list) and len(events) <= 1000, "invalid_learning_ledger") ++ selected = [e for e in events if start.date().isoformat() <= e["date"] < end.date().isoformat()] ++ totals = {} ++ for field in ("research_minutes", "execution_minutes", "reported_tokens", "cost_usd"): ++ values = [e["effort"][field] for e in selected] ++ require(all(v is None or (type(v) in (int, float) and math.isfinite(v) and v >= 0) for v in values), "invalid_effort") ++ totals[field] = {"known": round(sum(v for v in values if v is not None), 3), "unknown_cycles": sum(v is None for v in values)} ++ return {"basis": "owner snapshot; not live attestation", "as_of": data["as_of"], ++ "stale": (now - stamp).total_seconds() > 7 * 86400, ++ "health": health, "evidence_ref": data["evidence_ref"], "decisions": decisions, ++ "default": "Retain current policy/budgets; no new authority or maturity claim.", ++ "research_cycles": len(selected), "measured_effort": totals} ++ ++ + def collect(mode: str = "daily", now: datetime | None = None) -> dict: + require(mode in {"daily", "weekly", "monthly"}, "invalid_mode") + now = now or datetime.now(timezone.utc) +@@ -165,6 +204,7 @@ + "workplan": "FEP-WP-0008", "executor_dependency": "GLAS-WP-0012 / HFACT-WP-0001", + } + config = {"sources": []} ++ root_sha = None + rows = [] + events_seen = set() + total = 0 +@@ -213,6 +253,13 @@ + before = first - timedelta(days=1) + start = before.replace(day=1) + report["window"] = {"start": start.isoformat(), "end_exclusive": first.isoformat()} ++ try: ++ require(root_sha is not None, "missing_root_revision") ++ report["review"] = monthly_review(root_sha, now, start, first) ++ except (ValueError, KeyError, TypeError, AttributeError, OverflowError, httpx.HTTPError): ++ report["review"] = {"status": "unavailable", "health": "unknown", "decisions": [], ++ "default": "Retain current policy/budgets; no new authority or maturity claim."} ++ report["errors"].append("monthly_review_input_invalid_or_unavailable") + # Select latest event as of the end of the month, not latest today. + eligible_rows = [(e, d) for e, d in rows if datetime.fromisoformat(e["recorded_at"].replace("Z", "+00:00")) < first] + latest = reduce_events(eligible_rows, report["errors"]) diff --git a/integrations/activity-core/source.json b/integrations/activity-core/source.json new file mode 100644 index 0000000..fc2f91f --- /dev/null +++ b/integrations/activity-core/source.json @@ -0,0 +1,7 @@ +{ + "repository": "coulomb/activity-core", + "revision": "428f2d71b0f5ade11457e16d7b6341f571f6735f", + "resolver_sha256": "598ada41f2835ba08ba60ae7ca06c38acebaadc7c33b46d245a547107b2975e3", + "patched_resolver_sha256": "33aae2f3f0a17dfa90580c611de474064ca52b0aebf73939a9476a8560f46757", + "base_image": "forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd" +} diff --git a/integrations/activity-core/test_frontend_monthly_review.py b/integrations/activity-core/test_frontend_monthly_review.py new file mode 100644 index 0000000..4b61ff4 --- /dev/null +++ b/integrations/activity-core/test_frontend_monthly_review.py @@ -0,0 +1,87 @@ +import copy +import json +from datetime import datetime, timezone +from pathlib import Path +import pytest +from activity_core.context_resolvers import frontend_patterns as f + +NOW = datetime(2026, 10, 1, 7, tzinfo=timezone.utc) +INPUT = {'schema_version': 1, 'as_of': '2026-09-28T09:00:00Z', + 'health': {k: 'unverified' for k in ('schedule','collection','verification','publication','rollback','executor')}, + 'evidence_ref': 'docs/evidence/report.json', 'decisions': []} +EVENT = {'date': '2026-09-28', 'effort': {'research_minutes': 4, 'execution_minutes': 1, 'reported_tokens': None, 'cost_usd': None}} + + +def setup(monkeypatch, data=None, events=None, unavailable=False): + data = copy.deepcopy(INPUT if data is None else data) + events = [EVENT] if events is None else events + def raw(repo, sha, path): + assert repo == 'frontend-patterns' and sha == 'a'*40 + if path == 'feedback/sources.json': return b'{"schema_version":1,"sources":[]}' + if path == 'feedback/monthly-review-input.json': + if unavailable: raise ValueError('unavailable') + return json.dumps(data).encode() + if path == 'research/evolution/ledger.json': return json.dumps({'events': events}).encode() + if path == 'docs/evidence/report.json': return b'{}' + raise ValueError('unexpected or missing file') + monkeypatch.setattr(f, 'raw', raw) + monkeypatch.setattr(f, 'revision', lambda *args: 'a'*40) + + +def test_october_packet_with_no_consumers_retains_health_and_unknown_cost(monkeypatch): + setup(monkeypatch) + r=f.collect('monthly', NOW) + assert r['status']=='no_consumers' and r['model_calls']==0 + assert r['window']=={'start':'2026-09-01T00:00:00+02:00','end_exclusive':'2026-10-01T00:00:00+02:00'} + assert r['review']['health']['executor']=='unverified' + assert r['review']['measured_effort']['cost_usd']=={'known':0,'unknown_cycles':1} + assert r['review']['measured_effort']['research_minutes']=={'known':4,'unknown_cycles':0} + assert r['execution_ready'] is False + assert len(json.dumps(r,sort_keys=True,separators=(',',':'))) <= 3900 + + +def test_incomplete_input_degrades_without_losing_receipt_summary(monkeypatch): + setup(monkeypatch, unavailable=True) + r=f.collect('monthly', NOW) + assert r['status']=='degraded' and r['real_uses']==0 + assert r['review']['health']=='unknown' and r['review']['decisions']==[] + + +@pytest.mark.parametrize('change', [ + {'as_of':'2026-10-02T00:00:00Z'}, {'as_of':'2026-09-28T00:00:00'}, + {'evidence_ref':'../secret'}, {'decisions':[{}]*4}, + {'health':{'executor':'ready'}}, {'decisions':[{'question':'x','recommendation':'y'}]}, + {'evidence_ref':'docs/evidence/missing.json'}, +]) +def test_invalid_review_input_never_claims_health(monkeypatch, change): + data=copy.deepcopy(INPUT); data.update(change); setup(monkeypatch,data) + r=f.collect('monthly', NOW) + assert r['status']=='degraded' and r['review']['health']=='unknown' + + +def test_month_filter_and_missing_effort(monkeypatch): + old=copy.deepcopy(EVENT); old['date']='2026-08-31' + future=copy.deepcopy(EVENT); future['date']='2026-10-01' + unknown=copy.deepcopy(EVENT); unknown['effort']['research_minutes']=None + setup(monkeypatch, events=[old,future,EVENT,unknown]) + r=f.collect('monthly', NOW)['review'] + assert r['research_cycles']==2 + assert r['measured_effort']['research_minutes']=={'known':4,'unknown_cycles':1} + + +def test_stale_owner_snapshot_is_not_live_health(monkeypatch): + data=copy.deepcopy(INPUT); data['as_of']='2026-09-01T00:00:00Z'; setup(monkeypatch,data) + r=f.collect('monthly',NOW)['review'] + assert r['stale'] is True and 'not live attestation' in r['basis'] + + +@pytest.mark.parametrize('value', [-1, float('nan'), True]) +def test_invalid_effort_does_not_invent_totals(monkeypatch, value): + event=copy.deepcopy(EVENT); event['effort']['cost_usd']=value + setup(monkeypatch, events=[event]) + assert f.collect('monthly', NOW)['status']=='degraded' + + +def test_daily_does_not_require_monthly_packet(monkeypatch): + setup(monkeypatch, unavailable=True) + assert f.collect('daily', NOW)['status']=='no_consumers' diff --git a/integrations/activity-core/worker-image.patch b/integrations/activity-core/worker-image.patch new file mode 100644 index 0000000..957f008 --- /dev/null +++ b/integrations/activity-core/worker-image.patch @@ -0,0 +1,22 @@ +--- a/k8s/railiance/20-runtime.yaml ++++ b/k8s/railiance/20-runtime.yaml +@@ -2200,7 +2200,7 @@ + name: actcore-runtime-config + - secretRef: + name: actcore-runtime-secret +- image: forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd ++ image: forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437 + imagePullPolicy: IfNotPresent + name: worker + ports: +--- a/k8s/gitops/runtime.yaml ++++ b/k8s/gitops/runtime.yaml +@@ -1653,7 +1653,7 @@ + name: actcore-runtime-config + - secretRef: + name: actcore-runtime-secret +- image: forgejo.coulomb.social/coulomb/activity-core@sha256:713bddad10a41950f446100a8b370fca8ccdd0b8969cccae751e3870c9c63ccd ++ image: forgejo.coulomb.social/coulomb/activity-core@sha256:afd8a7af73132becba432e7b315d70f88d66676020169d5d8811641304136437 + imagePullPolicy: IfNotPresent + name: worker + ports: diff --git a/workplans/FEP-WP-0008-use-driven-improvement.md b/workplans/FEP-WP-0008-use-driven-improvement.md index 3fa4790..0d1300d 100644 --- a/workplans/FEP-WP-0008-use-driven-improvement.md +++ b/workplans/FEP-WP-0008-use-driven-improvement.md @@ -216,3 +216,31 @@ evidence, not a diagnosed scheduler outage. T03 retains cadence/sink verificatio with activity-core; no schedule was changed and no new task or workplan opened. [Recheck evidence](../docs/evidence/2026-09-28-loop-recheck.json). October 1's monthly packet remains due even with no consumers or executor. + +## Reporting failure diagnosed and candidate prepared — 2026-09-28 + +T03: the missing receipt is a real required-context failure, not a missed schedule. +The grant-aware worker promotion at activity-core `428f2d7` removed the frontend +resolver. Prepared and published a scoped overlay preserving all other Python +source and repository-grant identity. It restores registration and adds bounded +monthly owner-snapshot health/decisions plus measured effort/unknown counts. +58 focused tests, 17 GitOps tests, server dry-run and registry readback pass. +[Evidence and exact digest](../docs/evidence/2026-09-28-reporting-repair.json). + +The existing release runbook's 24-hour healthy interval is invalidated by the +failure; no routine release identity exists. Exact attended repair approval is +pending. Candidate publication and a future-clock October fixture are not production +repair or actual monthly completion. All three schedules remain enabled and unchanged. + +T01/T02: raw capability publication passes, hosted registration returns 404, and +the routed OpenBao registration credential is unavailable to the operator session. +Prepared a short [consumer instruction](../feedback/ConsumerIntegration.md); scanned +local relevant workplan titles but found no ready/active external task to enroll. +Blocked candidates and finished examples are not invented adoption evidence. +[Readiness record](../docs/evidence/2026-09-28-consumer-readiness.json). +Workplan remains blocked; no new task/workplan, consumer enrollment, secret disclosure +or pattern-editing authority was introduced. + +The user subsequently approved the exact attended worker repair; State Hub decision +`abdea390-1039-4da1-b129-33aad00b4396`. Promotion and post-rollout proof are now authorized; +this is not standing authority or approval to restore the older grant-unaware image.