Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,12 @@ deps.json
.intent/cache/
.venv_test/
.wup/

# Repository-local worktrees and operational state
/.worktrees/
/.subactor/leases/
/.subactor/sessions/
/.subactor/recovery/
/.subactor/receipts/
/.subactor/cache/
/.subactor/snapshots/
28 changes: 28 additions & 0 deletions .governance/docs/LOCAL_CI_PUBLICATION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Local CI publication policy — adopted reference

Canonical policy: [Wellmanifest/new-project 0.20.10](https://github.com/wellmanifest/new-project/blob/d5f77d83b3752477cfb95a535d0e1ce77f148576/docs/information/local-ci-publication.md).
Source revision: `d5f77d83b3752477cfb95a535d0e1ce77f148576`.
Canonical document SHA-256: `44803480f1d51f64eec81a62335b6725747f01b5f2de78105ebfc4017a7922c6`.

This managed file is an adoption reference. The authored document and its
metadata remain at the canonical Wellmanifest home; do not register this copy
as a new document owned by the adopting repository.

For Semcod and Subactor, prefer protected local OneDev verification followed
by the independent local Validator App. Resolve the actual protected profile,
observe existing reconciliation, require fresh verification of the PR head
merged with the current base, then invoke the trusted local Validator adapter
under existing publication authorization. The supported local adapter is
`subactor/validator-agent/bin/run-local-direct-pr.sh`; use its protected deployed
checkout and existing key reference as specified by the canonical runbook.
Never self-approve or merge directly.

A hosted Actions billing or capacity error does not prove local CI is unavailable.
Use hosted dispatch only when explicitly selected by the protected deployment.
Preserve all additional repository checks and required operating systems.
Retire a hosted check only after equivalent deployed local canary evidence and
independent policy review. Missing profiles are gaps, never successful coverage.

Keep declared, configured, deployed, verified and published evidence separate.
Read the canonical policy for the complete workflow, authority boundaries and
migration requirements. This reference grants no execution or merge authority.
2 changes: 1 addition & 1 deletion .governance/manifest.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
"stacks": [],
"standard": {
"id": "wellmanifest/new-project",
"version": "0.20.7"
"version": "0.20.11"
},
"ticket": {
"activeStatuses": [
Expand Down
2 changes: 1 addition & 1 deletion .governance/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
],
"standard": {
"id": "wellmanifest/new-project",
"version": "0.20.7"
"version": "0.20.11"
},
"ticket": {
"activeStatuses": [
Expand Down
23 changes: 12 additions & 11 deletions .governance/manifest.lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
".governance/diagnostics.json": "f132973d5becc5393355f1bb60673c29522eb61f1bea0956d7523214668edd67",
".governance/diagnostics.schema.json": "5c28e6a54319d106c234e63e1f65933533b5bfd5cdf6509a17b28362b56f86e1",
".governance/docs/BRANCH_INTENT_RECONCILIATION.md": "d17163b016e1ad8cf97408d528bf5a6443e931ea694e97191abc7c1e50586c3b",
".governance/docs/LOCAL_CI_PUBLICATION.md": "f30b778c8dc777be302ff346d3dbd144fc3a02fc957b178cc600bbec1219fc64",
".governance/error/GOV-AGENT-HOST.md": "a3679a63e6346946382dc510a8454b5c1c2851e694f7b3f4b82473764153a90f",
".governance/error/GOV-CHANGE-LEASE.md": "30530e7fd7c2eca9f4db0adec575dbc9b1bea139c2a640bfde0ae7c4b2ace116",
".governance/error/GOV-INTENT.md": "4dc29dbf4c39d18cd11a5ec1eccc257a06d2bea2f95b560aa58085672611d4a9",
Expand All @@ -41,9 +42,9 @@
".governance/governance_check.py": "305fc2fbf1c01a8a05e514346aa244977efabedd348379ebffd7e6562949fa17",
".governance/intent.schema.json": "9755f20cd189efe2205629781a6cf6b613bd93e9368416793c4de53256b0a9c0",
".governance/lock.schema.json": "ad80c98f800a4a3310870336dcdaf0aa689cc4988f71084d25d76bea2df1242f",
".governance/manifest.base.json": "532461b374f6727aadb8ad0a73fe99b3f5bf6c3cbd6ff151d53bee837fce0fff",
".governance/manifest.base.json": "e49a636499e17b46b399ebb0b0329df5ea79ed1d98f4264f21b666c732925d33",
".governance/manifest.schema.json": "5aa2ccd3f6898834d4e39a78342448145490be56aa132e16ac7c9d64acef8f73",
".governance/package-manifest.json": "3a148a2396bd8979c61a3df2adc6b0899c29b04e405e0047b73efa4b7d330cb9",
".governance/package-manifest.json": "a2ea77aca16d59282e1b60105521270ae112ebc52ddb3e08af3eeec26942dc3f",
".governance/precommit_standard_update.py": "c91e2bf9ae9d6ccc77bce0e61450c818a5961edee5bfde3b60426da88e296b0f",
".governance/remediation-intent.schema.json": "ab895e7ca0d83aef4c7d3eab674f14bcb0e0a0375298fdb3496d535dc9184d66",
".governance/remediation-intent.template.dsl.json": "a3eb01c54fe678f3fcebb88103ac4eb02f5dd24016b2ba9552814b5e442dfb34",
Expand All @@ -66,22 +67,22 @@
".governance/work-classification.schema.json": "f5c2b518238543589e4f8d3805cc6455e19d6919643644aaeae034abf472a467",
".governance/work-continuity.schema.json": "5134e6884ddaa4fb3a0ffd200d281afb0f3b868b06f71d65e3da6b42f6fe0830",
".governance/work_continuity.py": "2efb720b530cc295b45413a2bc7384a426bd29b5d9b20452035e5943294c18e4",
".governance/workspace_lifecycle_check.py": "8d9f11ccc7cf86c4b35835b4e5b7a2e44f5626b10466aff0d595da2c27c31ca2",
".governance/workspace_lifecycle_check.py": "f196f33c4884120ca216e65473f32b163f6c6d262624309cf0cbdc37063d181f",
".governance/worktree_guard.py": "b154f6e67626770ec11c9544d31a27b32d9c215ef73ffc9eb8f52e9c3a9b051b",
".governance/worktree_overlap_check.py": "f5ad2d2db98a240ca51cc7e2e404a726b521d8830721f1a0318127d4303fc9d9",
".governance/worktree_path_check.py": "6333676ac045246a655ea6fc042e83d5bbceef5b03b80eca50a12dc98a7aabeb",
".governance/worktrees.lock.json": "54c5c9ae00dca06cb5ad412a28b033245886c2c5bf45ae0db36e64e3f193ad37",
".governance/worktrees.schema.json": "5ba905865a72aea6a01afff1d06de028224651d2b444f6ac528cf65499d30148",
".governance/worktree_overlap_check.py": "86336eef38cfd1c2d421052e089e0523643d48ffa1c6fb7437b69cb78e17c785",
".governance/worktree_path_check.py": "d3309b76e2c91dd7f046b00322ec8cb48ef744b8b7908d70e475fedf95e5e196",
".governance/worktrees.lock.json": "9ed607dd339fd4ed30263d7de62231249447568e8e35c8b19fdc0231fca39fde",
".governance/worktrees.schema.json": "9cc10d126e06cafc87cc117f11b8b095676f461de4d168d2a1c2bb959f0fccd5",
".subactor/.gitignore": "dd223aed5e053f94c6808ac434368c16eeca7e77218f8426e8cf5e46ae441d03",
".subactor/manifest.json": "ab8b1cbe4052a6f0005a3c33a43fa2a70e8837cd32c18b4183d0d448c3a8cee2",
"AGENTS.md": "5a736ee536786caaeaa865fde29d019a0acede9488f9ec1928a628543e40baa0",
"AGENTS.md": "12641a33dcfc24c353834e95d09d4784c42ec035dcf350dd153b55eb02182364",
"CLAUDE.md": "48c8159bd17f0a7ab05989ee06e3aeec0aab07f64347fcc271140d9f650d7713",
"GEMINI.md": "b66a7d12c4c877110eb263a80b32c065c4c2d581743d72cd6e06ebbe6dc842da",
"project/governance-check.bat": "04f4fd3ba15abd6b874bde8fab0dd869402b84b9c83ae72da40c1a804b068045",
"project/governance-check.sh": "8eb977ff01a96e47455d227ed5ced949eb53ea19537f870d9016f803840e048e",
"project/new-ticket.sh": "82353ad45aee1df6764fd8afac5b950027d89507ea82fd3147c469aa9e556247",
"project/readme.sh": "b41a9c88374e6de0439284a4561fb11b1b482039bc5ba1bcf6683fd59b1a3968",
"scripts/install-agent-hosts.sh": "6a0878986f46d3379e12501b2bbdaf7726d71294da6ea3831ad1224d56809ee6",
"scripts/install-agent-hosts.sh": "0e3a59ed654de872c41f810dd2b7aded96a4bebd862db226ac27ffaf5e478ced",
"scripts/runtime.sh": "8d5c91808d3c126fc84018a12f0b39dd49194fb8b01c5e024932ff9cf2a7a7e2",
"wellmanifest_governance.py": "d6b71f091ffd88fb30c96f54162020d9aeb6e54555328834b68ccb21868ecc07",
"worktree-guard.yaml": "bea3d3cda9bd764f9e79b975da8f5360df894fdc04fca0407def88ebd49111b7"
Expand All @@ -91,7 +92,7 @@
"id": "wellmanifest/new-project",
"publicationStatus": "published",
"sourceRepository": "wellmanifest/new-project",
"sourceRevision": "9d7af1e63d46e0277da407286699ee50de726d17",
"version": "0.20.7"
"sourceRevision": "2cd39286dc0931870a8a60ee11c96dd6448b39e6",
"version": "0.20.11"
}
}
6 changes: 6 additions & 0 deletions .governance/package-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,12 @@
"target": ".governance/docs/BRANCH_INTENT_RECONCILIATION.md",
"strategy": "managed",
"executable": false
},
{
"source": "template/files/LOCAL_CI_PUBLICATION.template.md",
"target": ".governance/docs/LOCAL_CI_PUBLICATION.md",
"strategy": "managed",
"executable": false
}
]
}
18 changes: 9 additions & 9 deletions .governance/workspace_lifecycle_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ def load_worktrees_contract():
)
source = next((candidate for candidate in candidates if candidate.is_file()), None)
if source is None:
raise AuditError("the managed Worktrees v4 conformance module is missing")
spec = importlib.util.spec_from_file_location("workspace_worktrees_v4", source)
raise AuditError("the managed Worktrees conformance module is missing")
spec = importlib.util.spec_from_file_location("workspace_worktrees_contract", source)
if spec is None or spec.loader is None:
raise AuditError(f"cannot load Worktrees v4 conformance from {source}")
raise AuditError(f"cannot load Worktrees conformance from {source}")
module = importlib.util.module_from_spec(spec)
previous = sys.dont_write_bytecode
sys.dont_write_bytecode = True
try:
sys.modules[spec.name] = module
spec.loader.exec_module(module)
except (ImportError, OSError, ValueError) as error:
raise AuditError(f"cannot load Worktrees v4 conformance: {error}") from error
raise AuditError(f"cannot load Worktrees conformance: {error}") from error
finally:
sys.dont_write_bytecode = previous
sys.modules.pop(spec.name, None)
Expand Down Expand Up @@ -414,9 +414,9 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
path_style=path_style,
)
except (TypeError, ValueError) as error:
raise AuditError(f"Worktrees v4 inventory failed: {error}") from error
raise AuditError(f"Worktrees inventory failed: {error}") from error
if observed.get("readOnly") is not True:
raise AuditError("Worktrees v4 inventory did not declare readOnly=true")
raise AuditError("Worktrees inventory did not declare readOnly=true")
for entry in observed["entries"]:
layout_entries[Path(entry["path"])] = entry

Expand All @@ -428,7 +428,7 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
for checkout in sorted(checkouts, key=lambda item: str(item.path)):
layout = layout_entries.get(checkout.path)
if layout is None:
raise AuditError(f"Worktrees v4 inventory omitted {checkout.path}")
raise AuditError(f"Worktrees inventory omitted {checkout.path}")
duplicate = checkout.common_git_dir != authoritative_clone[checkout.identity]
anomalies = list(layout["anomalies"])
if duplicate:
Expand All @@ -446,7 +446,7 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
"cloneClassification": "duplicate-clone" if duplicate else "registered",
"anomalies": sorted(set(anomalies)),
})
return {"schema": "wellmanifest.worktrees/v4", "readOnly": True, "entries": entries}
return {"schema": contract.SCHEMA, "readOnly": True, "entries": entries}


def local_branch_findings(
Expand Down Expand Up @@ -650,7 +650,7 @@ def main(argv: list[str] | None = None) -> int:
evidence={"reason": str(error)},
)]
inventory = {
"schema": "wellmanifest.worktrees/v4",
"schema": None,
"readOnly": True,
"entries": [],
}
Expand Down
22 changes: 11 additions & 11 deletions .governance/worktree_overlap_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,26 +98,26 @@ class AuditError(RuntimeError):


def load_worktrees_contract():
"""Load the exact managed Worktrees v4 inventory without bytecode writes."""
"""Load the exact managed Worktrees inventory without bytecode writes."""
script = Path(__file__).resolve()
candidates = (
script.with_name("worktree_path_check.py"),
script.parent.parent / "subprojects" / "worktrees" / "conformance.py",
)
source = next((candidate for candidate in candidates if candidate.is_file()), None)
if source is None:
raise AuditError("the managed Worktrees v4 conformance module is missing")
spec = importlib.util.spec_from_file_location("overlap_worktrees_v4", source)
raise AuditError("the managed Worktrees conformance module is missing")
spec = importlib.util.spec_from_file_location("overlap_worktrees_contract", source)
if spec is None or spec.loader is None:
raise AuditError(f"cannot load Worktrees v4 conformance from {source}")
raise AuditError(f"cannot load Worktrees conformance from {source}")
module = importlib.util.module_from_spec(spec)
previous = sys.dont_write_bytecode
sys.dont_write_bytecode = True
try:
sys.modules[spec.name] = module
spec.loader.exec_module(module)
except (ImportError, OSError, ValueError) as error:
raise AuditError(f"cannot load Worktrees v4 conformance: {error}") from error
raise AuditError(f"cannot load Worktrees conformance: {error}") from error
finally:
sys.dont_write_bytecode = previous
sys.modules.pop(spec.name, None)
Expand Down Expand Up @@ -265,9 +265,9 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
path_style=path_style,
)
except (TypeError, ValueError) as error:
raise AuditError(f"Worktrees v4 inventory failed: {error}") from error
raise AuditError(f"Worktrees inventory failed: {error}") from error
if observed.get("readOnly") is not True:
raise AuditError("Worktrees v4 inventory did not declare readOnly=true")
raise AuditError("Worktrees inventory did not declare readOnly=true")
for entry in observed["entries"]:
layout_entries[Path(entry["path"])] = entry

Expand All @@ -279,7 +279,7 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
for checkout in sorted(checkouts, key=lambda item: str(item.path)):
layout = layout_entries.get(checkout.path)
if layout is None:
raise AuditError(f"Worktrees v4 inventory omitted {checkout.path}")
raise AuditError(f"Worktrees inventory omitted {checkout.path}")
duplicate = checkout.common_git_dir != authoritative_clone[checkout.identity]
anomalies = list(layout["anomalies"])
if duplicate:
Expand All @@ -297,7 +297,7 @@ def workspace_inventory(checkouts: list[Checkout]) -> dict[str, Any]:
"cloneClassification": "duplicate-clone" if duplicate else "registered",
"anomalies": sorted(set(anomalies)),
})
return {"schema": "wellmanifest.worktrees/v4", "readOnly": True, "entries": entries}
return {"schema": contract.SCHEMA, "readOnly": True, "entries": entries}


def path_ignored(relative: str, ignore: tuple[str, ...]) -> bool:
Expand Down Expand Up @@ -883,7 +883,7 @@ def report_payload(
"status": "passed" if not findings else "failed",
"scope": only_identity or "workspace",
"inventory": inventory or {
"schema": "wellmanifest.worktrees/v4",
"schema": None,
"readOnly": True,
"entries": [],
},
Expand Down Expand Up @@ -981,7 +981,7 @@ def main(argv: list[str] | None = None) -> int:
]
checkouts = []
inventory = {
"schema": "wellmanifest.worktrees/v4",
"schema": None,
"readOnly": True,
"entries": [],
}
Expand Down
Loading