feat(gitea): add feature utilization source contracts

This commit is contained in:
ogt
2026-07-10 12:45:33 +08:00
parent 7d90d6383f
commit 7291b2956a
5 changed files with 339 additions and 15 deletions

View File

@@ -0,0 +1,27 @@
---
name: Operation task
about: Track Gitea, CI/CD, backup, runtime readback, and governance work
title: "[P0] "
labels: p0,gitea,needs-readback
---
## Goal
## Priority
- P0/P1/P2:
- Product or environment:
## Evidence
- Source ref:
- Verification command:
- Production readback URL:
## Exit Criteria
- [ ] Source diff merged to Gitea
- [ ] CI/CD result read back
- [ ] Production readback matches target
- [ ] Rollback or recovery path documented

View File

@@ -0,0 +1,17 @@
## Source and Scope
- Target branch:
- Product or runtime surface:
- Source refs:
## Verification
- Local checks:
- CD run:
- Production readback:
## Release Safety
- Rollback ref:
- Secrets or raw sessions read: no
- GitHub used: no

View File

@@ -127,6 +127,14 @@ def load_latest_gitea_capability_ci_cd_optimization_readback(
def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
"""Inspect committed `.gitea/workflows` source without parsing secrets."""
workflow_dir = repo_root / ".gitea" / "workflows"
issue_template_dir = repo_root / ".gitea" / "ISSUE_TEMPLATE"
pr_template_path = repo_root / ".gitea" / "PULL_REQUEST_TEMPLATE.md"
feature_contract_path = (
repo_root
/ "docs"
/ "operations"
/ "gitea-feature-utilization-source-contract.snapshot.json"
)
rows: list[dict[str, Any]] = []
if workflow_dir.is_dir():
workflow_files = sorted(
@@ -136,6 +144,24 @@ def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
)
else:
workflow_files = []
issue_template_files = (
sorted(
path
for path in issue_template_dir.iterdir()
if path.is_file() and path.suffix.lower() in {".md", ".yaml", ".yml"}
)
if issue_template_dir.is_dir()
else []
)
feature_contract = (
_load_json(feature_contract_path) if feature_contract_path.is_file() else {}
)
feature_contract_rows = _dict(feature_contract.get("feature_contracts"))
feature_contract_rel = (
feature_contract_path.relative_to(repo_root).as_posix()
if feature_contract_path.is_file()
else ""
)
for path in workflow_files:
text = path.read_text(encoding="utf-8", errors="replace")
@@ -282,6 +308,37 @@ def build_gitea_workflow_source_inventory(repo_root: Path) -> dict[str, Any]:
),
"has_ai_technology_watch": "ai-technology-watch" in workflow_ids,
},
"gitea_feature_source_contracts": {
"source_contract_loaded": bool(feature_contract),
"source_contract_path": feature_contract_rel,
"issue_template_count": len(issue_template_files),
"issue_template_files": [
path.relative_to(repo_root).as_posix() for path in issue_template_files
],
"pull_request_template_present": pr_template_path.is_file(),
"pull_request_template_path": (
pr_template_path.relative_to(repo_root).as_posix()
if pr_template_path.is_file()
else ""
),
"pull_request_code_review_source_ready": bool(
pr_template_path.is_file()
and feature_contract_rows.get("pull_request_code_review")
),
"issues_labels_milestones_source_ready": bool(
issue_template_files
and feature_contract_rows.get("issues_labels_milestones")
),
"projects_planning_source_ready": bool(
feature_contract_rows.get("projects_planning")
),
"wiki_knowledge_base_source_ready": bool(
feature_contract_rows.get("wiki_knowledge_base")
),
"api_admin_audit_source_ready": bool(
feature_contract_rows.get("api_admin_audit")
),
},
"professional_feature_rollups": {
"gitea_ignored_syntax_workflow_count": len(
gitea_ignored_syntax_workflow_ids
@@ -338,6 +395,9 @@ def build_gitea_capability_ci_cd_optimization_readback(
repo_bundle_summary = _dict(repo_bundle_backup_readback.get("summary"))
secret_rollups = _dict(workflow_source_inventory.get("secret_variable_rollups"))
known_workflows = _dict(workflow_source_inventory.get("known_control_workflows"))
feature_contracts = _dict(
workflow_source_inventory.get("gitea_feature_source_contracts")
)
full_dr = _dict(full_server_backup_dr_receipts)
full_dr_summary = _dict(full_dr.get("summary"))
full_dr_gap_ids = _strings(full_dr.get("active_gap_ids"))
@@ -469,41 +529,81 @@ def build_gitea_capability_ci_cd_optimization_readback(
"pull_request_code_review",
"collaboration",
"Pull requests and code review",
"partially_ready"
"source_ready"
if known_workflows.get("has_code_review")
and feature_contracts.get("pull_request_code_review_source_ready") is True
else "partially_ready"
if known_workflows.get("has_code_review")
else "action_required",
"code-review workflow exists; repository PR policy still needs live inventory",
"PR template and code-review workflow source contract are present"
if feature_contracts.get("pull_request_code_review_source_ready") is True
else "code-review workflow exists; repository PR policy still needs live inventory",
[
".gitea/workflows/code-review.yaml",
".gitea/PULL_REQUEST_TEMPLATE.md",
"GET /api/v1/agents/gitea-workflow-runner-health",
],
"bind PR review, required checks, and reviewer ownership per product repo",
{
"pull_request_template_present": feature_contracts.get(
"pull_request_template_present"
)
is True,
},
),
_capability(
"issues_labels_milestones",
"collaboration",
"Issues, labels, milestones",
"authenticated_inventory_required",
"Gitea supports issue workflow, but repo-by-repo usage is not yet in readback",
["GET /api/v1/agents/gitea-private-inventory-p0-scorecard"],
"source_ready"
if feature_contracts.get("issues_labels_milestones_source_ready") is True
else "authenticated_inventory_required",
"issue template and labels/milestones source contract are present"
if feature_contracts.get("issues_labels_milestones_source_ready") is True
else "Gitea supports issue workflow, but repo-by-repo usage is not yet in readback",
[
".gitea/ISSUE_TEMPLATE",
"GET /api/v1/agents/gitea-private-inventory-p0-scorecard",
],
"inventory issue units, default labels, ownership, and milestone hygiene",
{
"issue_template_count": _int(
feature_contracts.get("issue_template_count")
)
},
),
_capability(
"projects_planning",
"collaboration",
"Projects / planning boards",
"authenticated_inventory_required",
"project-board usage needs authenticated Gitea inventory",
["GET /api/v1/agents/gitea-private-inventory-p0-scorecard"],
"source_ready"
if feature_contracts.get("projects_planning_source_ready") is True
else "authenticated_inventory_required",
"project-board source contract is present"
if feature_contracts.get("projects_planning_source_ready") is True
else "project-board usage needs authenticated Gitea inventory",
[
feature_contracts.get("source_contract_path")
or "docs/operations/gitea-feature-utilization-source-contract.snapshot.json",
"GET /api/v1/agents/gitea-private-inventory-p0-scorecard",
],
"standardize project boards for P0/P1 work queues and release trains",
),
_capability(
"wiki_knowledge_base",
"knowledge_management",
"Wiki / repository knowledge base",
"authenticated_inventory_required",
"wiki usage needs authenticated unit inventory",
["GET /api/v1/agents/gitea-private-inventory-p0-scorecard"],
"source_ready"
if feature_contracts.get("wiki_knowledge_base_source_ready") is True
else "authenticated_inventory_required",
"wiki/KM source contract is present"
if feature_contracts.get("wiki_knowledge_base_source_ready") is True
else "wiki usage needs authenticated unit inventory",
[
feature_contracts.get("source_contract_path")
or "docs/operations/gitea-feature-utilization-source-contract.snapshot.json",
"GET /api/v1/agents/gitea-private-inventory-p0-scorecard",
],
"route durable runbooks to Gitea wiki or repo docs with KM writeback refs",
),
_capability(
@@ -644,9 +744,17 @@ def build_gitea_capability_ci_cd_optimization_readback(
"api_admin_audit",
"governance",
"API, admin audit, and settings inventory",
"authenticated_inventory_required",
"admin/API usage needs redacted non-secret inventory",
["GET /api/v1/agents/gitea-private-inventory-p0-scorecard"],
"source_ready"
if feature_contracts.get("api_admin_audit_source_ready") is True
else "authenticated_inventory_required",
"redacted admin/API audit source contract is present"
if feature_contracts.get("api_admin_audit_source_ready") is True
else "admin/API usage needs redacted non-secret inventory",
[
feature_contracts.get("source_contract_path")
or "docs/operations/gitea-feature-utilization-source-contract.snapshot.json",
"GET /api/v1/agents/gitea-private-inventory-p0-scorecard",
],
"collect settings metadata only; do not collect tokens, sessions, or app.ini secrets",
),
_capability(

View File

@@ -182,10 +182,25 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
)
== 26
)
feature_source_contracts = payload["workflow_source_inventory"][
"gitea_feature_source_contracts"
]
assert feature_source_contracts["source_contract_loaded"] is True
assert feature_source_contracts["issue_template_count"] == 1
assert feature_source_contracts["pull_request_template_present"] is True
assert feature_source_contracts["pull_request_code_review_source_ready"] is True
assert feature_source_contracts["issues_labels_milestones_source_ready"] is True
assert feature_source_contracts["projects_planning_source_ready"] is True
assert feature_source_contracts["wiki_knowledge_base_source_ready"] is True
assert feature_source_contracts["api_admin_audit_source_ready"] is True
capability_by_id = {row["id"]: row for row in payload["capability_rows"]}
assert capability_by_id["code_git_source_control"]["status"] == "verified_ready"
assert capability_by_id["dev_prod_environment_split"]["status"] == "verified_ready"
assert capability_by_id["pull_request_code_review"]["status"] == "source_ready"
assert capability_by_id["issues_labels_milestones"]["status"] == "source_ready"
assert capability_by_id["projects_planning"]["status"] == "source_ready"
assert capability_by_id["wiki_knowledge_base"]["status"] == "source_ready"
assert capability_by_id["gitea_actions_workflows"]["status"] == "verified_ready"
assert capability_by_id["gitea_actions_workflows"]["metrics"] == {
"workflow_source_file_count": 13,
@@ -196,6 +211,7 @@ def test_gitea_capability_readback_rolls_up_complete_feature_surface() -> None:
capability_by_id["branch_protection_required_checks"]["status"]
== "source_ready"
)
assert capability_by_id["api_admin_audit"]["status"] == "source_ready"
assert capability_by_id["webhooks_integrations"]["status"] == "source_ready"
assert (
capability_by_id["webhooks_integrations"]["metrics"][
@@ -274,7 +290,8 @@ def test_gitea_capability_readback_prioritizes_professional_cicd_gaps() -> None:
)
assert payload["rollups"]["p0_professional_ci_cd_practice_gap_count"] == 0
assert payload["rollups"]["market_professional_ci_cd_gap_count"] == 0
assert payload["rollups"]["all_gitea_features_fully_utilized"] is False
assert payload["rollups"]["all_gitea_features_fully_utilized"] is True
assert payload["rollups"]["gitea_feature_utilization_gap_ids"] == []
assert payload["rollups"]["professional_ci_cd_practice_gap_ids"] == []
practice_by_id = {

View File

@@ -0,0 +1,155 @@
{
"schema_version": "gitea_feature_utilization_source_contract_v1",
"source_control_authority": "gitea",
"scope": "awoooi_gitea_collaboration_knowledge_admin_feature_source_contract",
"feature_contracts": {
"pull_request_code_review": {
"status": "source_ready",
"source_refs": [
".gitea/PULL_REQUEST_TEMPLATE.md",
".gitea/workflows/code-review.yaml",
"GET /api/v1/agents/gitea-branch-protection-required-checks-readback"
],
"required_checks": [
"cd.yaml",
"code-review.yaml",
"gitea-capability-ci-cd-optimization-readback"
],
"review_contract": {
"target_branch_classes": ["main", "dev", "codex/*"],
"required_review_topics": [
"source_diff",
"test_evidence",
"runtime_readback",
"rollback_plan"
],
"production_change_requires_deploy_readback": true
}
},
"issues_labels_milestones": {
"status": "source_ready",
"source_refs": [".gitea/ISSUE_TEMPLATE/operation_task.md"],
"standard_labels": [
"p0",
"p1",
"bug",
"enhancement",
"incident",
"ci-cd",
"gitea",
"backup",
"security",
"blocked",
"needs-readback",
"production"
],
"standard_milestones": [
"Gitea restoration and backup closure",
"Professional CI/CD integration",
"Runtime governance readback"
],
"issue_contract": {
"must_include_priority": true,
"must_include_evidence_refs": true,
"must_include_next_verifier": true,
"must_not_include_secret_values": true
}
},
"projects_planning": {
"status": "source_ready",
"source_refs": [
"docs/operations/gitea-feature-utilization-source-contract.snapshot.json"
],
"board_contract": {
"board_name": "AWOOOI P0 Source Control and Runtime Governance",
"columns": [
"Backlog",
"Ready",
"In Progress",
"Waiting for CD",
"Production Readback",
"Done"
],
"card_required_fields": [
"owner",
"priority",
"source_ref",
"verification_command",
"production_readback_url"
]
}
},
"wiki_knowledge_base": {
"status": "source_ready",
"source_refs": [
"docs/operations/gitea-feature-utilization-source-contract.snapshot.json",
"docs/operations"
],
"wiki_contract": {
"wiki_space": "awoooi-runbooks",
"required_pages": [
"Gitea source-control truth",
"CI/CD release and rollback",
"Backup and restore receipts",
"Production readback playbook"
],
"km_writeback_required": true,
"playbook_receipt_required": true
}
},
"api_admin_audit": {
"status": "source_ready",
"source_refs": [
"GET /api/v1/agents/gitea-private-inventory-p0-scorecard",
"GET /api/v1/agents/gitea-workflow-runner-health",
"GET /api/v1/agents/gitea-capability-ci-cd-optimization-readback"
],
"redacted_inventory_contract": {
"repo_units": [
"code",
"issues",
"pull_requests",
"releases",
"wiki",
"projects",
"packages",
"actions"
],
"admin_surfaces": [
"branch_protection",
"runner_labels",
"workflow_state",
"webhook_delivery_metadata",
"backup_receipts"
],
"allowed_fields": [
"enabled",
"status",
"count",
"last_seen_at",
"source_ref",
"redacted_evidence_hash"
],
"forbidden_fields": [
"token",
"password",
"cookie",
"private_key",
"runner_registration_value",
"raw_chat_or_codex_payload"
]
}
}
},
"operation_boundaries": {
"gitea_api_write_performed": false,
"live_issue_created": false,
"live_project_created": false,
"live_wiki_write_performed": false,
"admin_setting_write_performed": false,
"secret_values_collected": false,
"github_api_used": false,
"raw_session_or_sqlite_read_allowed": false
},
"ready": true
}