@arbiterforge/ca-pi 0.15.10 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +45 -0
- package/plugins/ca-pi/SKILLS.md +1 -1
- package/plugins/ca-pi/agents/infra-author.md +7 -1
- package/plugins/ca-pi/agents/scout.md +40 -8
- package/plugins/ca-pi/generated/command-catalog.json +1 -1
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-darwin-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-amd64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-linux-arm64 +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-amd64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/ca-artifact-windows-arm64.exe +0 -0
- package/plugins/ca-pi/helpers/artifacts/release.json +104 -6
- package/plugins/ca-pi/hooks/_activationlib.py +97 -13
- package/plugins/ca-pi/hooks/_arbiterstatelib.py +7 -2
- package/plugins/ca-pi/hooks/_artifactauthoritylib.py +519 -16
- package/plugins/ca-pi/hooks/_artifactlib.py +244 -7
- package/plugins/ca-pi/hooks/_artifactpromptlib.py +106 -2
- package/plugins/ca-pi/hooks/_bashguardlib.py +23 -8
- package/plugins/ca-pi/hooks/_contextreportlib.py +564 -6
- package/plugins/ca-pi/hooks/_contextselectlib.py +464 -0
- package/plugins/ca-pi/hooks/_contextsnapshotlib.py +999 -0
- package/plugins/ca-pi/hooks/_debughandofflib.py +767 -0
- package/plugins/ca-pi/hooks/_hooklib.py +2 -1
- package/plugins/ca-pi/hooks/_host.py +1 -1
- package/plugins/ca-pi/hooks/_intentlib.py +5 -5
- package/plugins/ca-pi/hooks/_protectedlib.py +3 -3
- package/plugins/ca-pi/hooks/_protectedstatelib.py +152 -2
- package/plugins/ca-pi/hooks/_provenancelib.py +604 -34
- package/plugins/ca-pi/hooks/_readinjectlib.py +131 -1
- package/plugins/ca-pi/hooks/_sensitivelib.py +28 -14
- package/plugins/ca-pi/hooks/artifact-authority-hook.py +1 -0
- package/plugins/ca-pi/hooks/artifact-authority.py +25 -1
- package/plugins/ca-pi/hooks/debug-handoff.py +85 -0
- package/plugins/ca-pi/hooks/doctor.py +4 -2
- package/plugins/ca-pi/hooks/git-enforce.py +7 -6
- package/plugins/ca-pi/hooks/hostapi.py +1 -1
- package/plugins/ca-pi/hooks/init-codearbiter.py +143 -15
- package/plugins/ca-pi/hooks/prompt-submit.py +14 -0
- package/plugins/ca-pi/hooks/session-start.py +26 -7
- package/plugins/ca-pi/includes/artifacts.md +41 -0
- package/plugins/ca-pi/includes/author-tdd-workflow.md +16 -4
- package/plugins/ca-pi/includes/helper-invocation.md +128 -0
- package/plugins/ca-pi/includes/pi-host-notes.md +13 -0
- package/plugins/ca-pi/includes/routing-table.md +1 -1
- package/plugins/ca-pi/includes/security-gate-record.md +5 -3
- package/plugins/ca-pi/package.json +1 -1
- package/plugins/ca-pi/routines/INDEX.md +1 -1
- package/plugins/ca-pi/routines/commit-gate/SKILL.md +5 -3
- package/plugins/ca-pi/routines/context-check/SKILL.md +103 -17
- package/plugins/ca-pi/routines/context-creation/SKILL.md +290 -54
- package/plugins/ca-pi/routines/debug/SKILL.md +303 -55
- package/plugins/ca-pi/routines/debug/references/debug-handoff.schema.json +879 -0
- package/plugins/ca-pi/routines/debug/references/handoff.md +155 -0
- package/plugins/ca-pi/routines/decompose/SKILL.md +13 -0
- package/plugins/ca-pi/routines/subagent-driven-development/SKILL.md +34 -0
- package/plugins/ca-pi/routines/tdd/SKILL.md +91 -17
- package/plugins/ca-pi/skills/ca-commit/SKILL.md +5 -3
- package/plugins/ca-pi/skills/ca-context-check/SKILL.md +103 -17
- package/plugins/ca-pi/skills/ca-create-context/SKILL.md +290 -54
- package/plugins/ca-pi/skills/ca-debug/SKILL.md +303 -55
- package/plugins/ca-pi/skills/ca-decompose/SKILL.md +13 -0
- package/plugins/ca-pi/skills/ca-feature/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-fix/SKILL.md +36 -3
- package/plugins/ca-pi/skills/ca-init/SKILL.md +19 -0
- package/plugins/ca-pi/skills/ca-review/SKILL.md +33 -4
- package/plugins/ca-pi/skills/ca-status/SKILL.md +5 -0
- package/plugins/ca-pi/skills/ca-task/SKILL.md +55 -8
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ project context. You decide. codeArbiter enforces.
|
|
|
10
10
|
<img alt="Claude Code plugin" src="https://img.shields.io/badge/Claude_Code-plugin-d97757">
|
|
11
11
|
<img alt="Codex plugin" src="https://img.shields.io/badge/OpenAI_Codex-plugin-10a37f">
|
|
12
12
|
<img alt="Pi Feature Forge preview" src="https://img.shields.io/badge/ca--pi-Feature_Forge_preview-d97757">
|
|
13
|
-
<img alt="version 2.
|
|
13
|
+
<img alt="version 2.24.0" src="https://img.shields.io/badge/version-2.24.0-2b7489">
|
|
14
14
|
<img alt="core lanes" src="https://img.shields.io/badge/core_lanes-18-555">
|
|
15
15
|
<img alt="skills" src="https://img.shields.io/badge/skills-22-555">
|
|
16
16
|
<img alt="agents" src="https://img.shields.io/badge/agents-20-555">
|
package/package.json
CHANGED
|
@@ -4,6 +4,51 @@ All notable changes to `ca-pi` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.16.0] - 2026-10-03
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Add bounded task-context selection, per-document freshness and attempt accounting
|
|
12
|
+
to the shared governance payload, with explicit actor-delivery gaps.
|
|
13
|
+
- Carry shared context resources while preserving Pi's refusal of the unqualified
|
|
14
|
+
repository-context write workflow. No live Pi qualification is claimed.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Preserve Unicode whitespace in activation frontmatter while requiring a real
|
|
19
|
+
initialized marker outside fenced code and comments.
|
|
20
|
+
- Synchronize the packaged adapter version with its release manifest.
|
|
21
|
+
- Validate diagnostic handoffs before repair or task follow-ups, preserving
|
|
22
|
+
the caller's authority and checking that the evidence is current.
|
|
23
|
+
- Keep diagnostic outcomes, regression reuse and helper invocation consistent
|
|
24
|
+
across the generated host packages.
|
|
25
|
+
|
|
26
|
+
## [0.15.13] - 2026-10-04
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- Synchronize the shared evidence-context reader with native UTF-8 canonical
|
|
31
|
+
bytes while preserving digest and frozen-context checks.
|
|
32
|
+
|
|
33
|
+
## [0.15.12] - 2026-10-03
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- Shared authority library: recovering an already-abandoned oversized review now reports
|
|
38
|
+
`request was already abandoned` instead of a misleading binding failure. Carries the Claude
|
|
39
|
+
Code 2.1.286 review-correlation fix (tagged `resolvedModel`, `SubagentHandback` reports),
|
|
40
|
+
which applies only to the Claude host.
|
|
41
|
+
- The crypto/secret commit gate (H-09b/H-10b) no longer expires a recorded pass after 30 minutes.
|
|
42
|
+
A pass now stays valid for exactly the lines it reviewed, in the files it reviewed them in,
|
|
43
|
+
like the migration gate; any new, changed, or moved sensitive line still blocks until reviewed.
|
|
44
|
+
|
|
45
|
+
## [0.15.11] - 2026-10-03
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Synchronize the shared kernel's explicit completion-review evidence contract.
|
|
50
|
+
This does not enable the unsupported Pi native review-authority path.
|
|
51
|
+
|
|
7
52
|
## [0.15.10] - 2026-10-03
|
|
8
53
|
|
|
9
54
|
### Changed
|
package/plugins/ca-pi/SKILLS.md
CHANGED
|
@@ -77,7 +77,7 @@ skill is invoked — never bulk-read this directory.
|
|
|
77
77
|
|
|
78
78
|
| Skill | Purpose |
|
|
79
79
|
|---|---|
|
|
80
|
-
| `/ca-debug` | Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff
|
|
80
|
+
| `/ca-debug` | Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff, including a bounded unresolved result. Not for implementing a known fix, new features, or explanation-only questions. |
|
|
81
81
|
|
|
82
82
|
### Review
|
|
83
83
|
|
|
@@ -9,7 +9,12 @@ model: sonnet
|
|
|
9
9
|
|
|
10
10
|
# Infrastructure Author Agent
|
|
11
11
|
|
|
12
|
-
Infrastructure implementation executor. Write IaC, container, CI/CD, and deployment
|
|
12
|
+
Infrastructure implementation executor. Write IaC, container, CI/CD, and deployment
|
|
13
|
+
configuration only after the owning route clears its prerequisite: approved
|
|
14
|
+
feature criteria (and a plan where applicable) for `/feature`, or the original
|
|
15
|
+
caller's repair authority and a bug-origin regression obligation for `/fix`.
|
|
16
|
+
The regression must be red for the
|
|
17
|
+
right reason before implementation. Do not fabricate a feature artifact for a fix.
|
|
13
18
|
|
|
14
19
|
## Required Reading at the Start of Every Task
|
|
15
20
|
|
|
@@ -17,6 +22,7 @@ Read in full before writing any infrastructure code:
|
|
|
17
22
|
|
|
18
23
|
1. `<project-root>/.codearbiter/tech-stack.md` — IaC tool (OpenTofu, Ansible, Helm, etc.), container runtime, CI/CD system, approved registries
|
|
19
24
|
2. `<project-root>/.codearbiter/security-controls.md` — security boundaries, approved secrets store, compliance requirements affecting infrastructure
|
|
25
|
+
3. `<plugin-root>/includes/author-tdd-workflow.md` — the shared six-step TDD execution order. Read it; do not carry a remembered copy.
|
|
20
26
|
|
|
21
27
|
## Security Rules
|
|
22
28
|
|
|
@@ -18,16 +18,48 @@ Dispatched by `decision-variance` and `context-creation` to scan an assigned cod
|
|
|
18
18
|
- Codebase sections have natural ownership boundaries that map to scout assignments.
|
|
19
19
|
- Parallel evidence gathering across multiple areas is needed.
|
|
20
20
|
|
|
21
|
-
Under ~50 files, `decision-variance` scans inline.
|
|
22
|
-
dispatches its six fixed,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
Under ~50 files, `decision-variance` scans inline. When a qualified context
|
|
22
|
+
profile becomes available, `context-creation` dispatches its six fixed,
|
|
23
|
+
isolated scout assignments because its report-only synthesis boundary depends
|
|
24
|
+
on the orchestrator not reading raw source.
|
|
25
|
+
|
|
26
|
+
## Context-creation assignment
|
|
27
|
+
|
|
28
|
+
The shared `scout` frontmatter includes Bash for existing `decision-variance`
|
|
29
|
+
assignments. It is therefore not a context-creation containment profile.
|
|
30
|
+
`context-creation` must BLOCK before dispatch until the active host supplies a
|
|
31
|
+
separate, fresh child identity with host-enforced read-only restriction and an
|
|
32
|
+
observed denied benign write, successful source read, and bounded report
|
|
33
|
+
delivery. A prose instruction to avoid writes is not enforcement. An explicit
|
|
34
|
+
session-only `context-scout` may retain Bash solely for exact, frozen
|
|
35
|
+
`git hash-object -- '<source path>'` reads when a caller-owned command guard and
|
|
36
|
+
read-only OS phase are independently qualified. No other Bash command is part
|
|
37
|
+
of this assignment, and the inherited shared `scout` role remains ineligible. This
|
|
38
|
+
assignment preserves report-only synthesis; the orchestrator uses reports and
|
|
39
|
+
does not load raw source after pre-flight. A qualified context scout must emit
|
|
40
|
+
the versioned closed report envelope accepted by `_contextreportlib`, bound to
|
|
41
|
+
its assignment, attempt, snapshot and scope. A trusted read-only hash collector
|
|
42
|
+
must supply each cited digest when the restricted child has no Bash.
|
|
43
|
+
|
|
44
|
+
For context-creation, report each assigned category even when the search finds
|
|
45
|
+
no match. Use the closed outcome vocabulary: `observed`, `not_applicable`,
|
|
46
|
+
`not_found_in_scope`, `not_inspected`, `ambiguous`, `failed`, or `oversize`.
|
|
47
|
+
Negative results name the searched scope and predicates; `not_applicable`
|
|
48
|
+
also needs a reason why the domain does not apply. Do not turn a missing report
|
|
49
|
+
or an incomplete search into a negative finding. Keep contradictory evidence
|
|
50
|
+
with both citations and describe the dispute without choosing a policy. A
|
|
51
|
+
reported convention, instruction, package script or ADR remains evidence:
|
|
52
|
+
never assign approval or policy authority from confidence, a source label or
|
|
53
|
+
the scout's own judgment. Do not propose a task or local ADR from an observed
|
|
54
|
+
pattern. This context-creation report rule does not change the separate
|
|
55
|
+
decision-variance Markdown assignment below.
|
|
56
|
+
|
|
57
|
+
## Decision-variance assignment format
|
|
26
58
|
|
|
27
59
|
The dispatching skill provides:
|
|
28
60
|
|
|
29
61
|
```
|
|
30
|
-
You are a Scout for the decision-variance
|
|
62
|
+
You are a Scout for the decision-variance skill.
|
|
31
63
|
|
|
32
64
|
Your scope: <specific paths or areas, e.g., "backend/src/auth/", "helm/", ".codearbiter/decisions/">
|
|
33
65
|
|
|
@@ -49,9 +81,9 @@ Constraints:
|
|
|
49
81
|
|
|
50
82
|
## Output Template
|
|
51
83
|
|
|
52
|
-
|
|
84
|
+
Decision-variance scouts return this exact format.
|
|
53
85
|
|
|
54
|
-
**Hash field:** For each cited file
|
|
86
|
+
**Hash field:** For decision-variance assignments, emit each cited file's `git hash-object <path>` oid in the `hash` field. That legacy role has Bash. A context-creation assignment needs a digest in the method and shape required by the closed report decoder. A qualified context-specific Bash route may use only its frozen exact `git hash-object -- '<source path>'` commands and must label the result `git-blob-normalized-sha1`. A different qualified read-only collector may provide `sha256-raw`, retaining that distinct method identity. A missing actual digest blocks the citation; neither the caller's snapshot checksum nor an injected answer substitutes for the child's or trusted collector's observed result. A git oid is not a code excerpt; the "no excerpts" rule (file path and line numbers only) is not violated by including an oid.
|
|
55
87
|
|
|
56
88
|
```markdown
|
|
57
89
|
# Scout Report — <scope>
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
},
|
|
162
162
|
"debug": {
|
|
163
163
|
"name": "debug",
|
|
164
|
-
"description": "Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff
|
|
164
|
+
"description": "Investigate an unexplained defect or unexpected behavior without changing application code. Use for root-cause diagnosis and an evidence-backed handoff, including a bounded unresolved result. Not for implementing a known fix, new features, or explanation-only questions.",
|
|
165
165
|
"skillPath": "skills/ca-debug/SKILL.md",
|
|
166
166
|
"visibility": "advanced",
|
|
167
167
|
"workflow": "change",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -6,33 +6,131 @@
|
|
|
6
6
|
"binaries": {
|
|
7
7
|
"darwin/amd64": {
|
|
8
8
|
"file": "ca-artifact-darwin-amd64",
|
|
9
|
-
"sha256": "
|
|
9
|
+
"sha256": "27fc51465a79c1525b1300b347cee4d09afde3c7b0d845414659302f5bbca2f7",
|
|
10
10
|
"native_tested": true
|
|
11
11
|
},
|
|
12
12
|
"darwin/arm64": {
|
|
13
13
|
"file": "ca-artifact-darwin-arm64",
|
|
14
|
-
"sha256": "
|
|
14
|
+
"sha256": "3a3d61be18eba426db4f260b9cbae0d3d3c89f47efe184395d7f011cc3b4f59a",
|
|
15
15
|
"native_tested": true
|
|
16
16
|
},
|
|
17
17
|
"linux/amd64": {
|
|
18
18
|
"file": "ca-artifact-linux-amd64",
|
|
19
|
-
"sha256": "
|
|
19
|
+
"sha256": "3b6178bb54d6a19fc56d99f8fced862ae151605a0373297a69e130d3857a8406",
|
|
20
20
|
"native_tested": true
|
|
21
21
|
},
|
|
22
22
|
"linux/arm64": {
|
|
23
23
|
"file": "ca-artifact-linux-arm64",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "a5259074098932f815f33d3e1dea98e6d9a04277d1ada958469905da67d29437",
|
|
25
25
|
"native_tested": true
|
|
26
26
|
},
|
|
27
27
|
"windows/amd64": {
|
|
28
28
|
"file": "ca-artifact-windows-amd64.exe",
|
|
29
|
-
"sha256": "
|
|
29
|
+
"sha256": "8339c077262f861631631de49bca7cdafec5e0730b9e3676fd2db36f3c119036",
|
|
30
30
|
"native_tested": true
|
|
31
31
|
},
|
|
32
32
|
"windows/arm64": {
|
|
33
33
|
"file": "ca-artifact-windows-arm64.exe",
|
|
34
|
-
"sha256": "
|
|
34
|
+
"sha256": "f7b193cf0d1eb9ecd233bf1588f6290c2fb8bc41ad327918a740beb2099f719c",
|
|
35
35
|
"native_tested": true
|
|
36
36
|
}
|
|
37
|
+
},
|
|
38
|
+
"context_qualification": {
|
|
39
|
+
"darwin/amd64": {
|
|
40
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
41
|
+
"workflow": ".github/workflows/ci.yml",
|
|
42
|
+
"run_id": "37242446770",
|
|
43
|
+
"binary_sha256": "27fc51465a79c1525b1300b347cee4d09afde3c7b0d845414659302f5bbca2f7",
|
|
44
|
+
"observation_sha256": "a95ce59522b1f4c1552a906f8d50989ca021f6b3017aadead4ca6f337a1cbc0c",
|
|
45
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
46
|
+
"native_cases": [
|
|
47
|
+
"TestContextBoundedRender",
|
|
48
|
+
"TestContextDocumentContract",
|
|
49
|
+
"TestContextMarkdownPreservation",
|
|
50
|
+
"TestContextMutationAdmission",
|
|
51
|
+
"TestContextRecoveryAndPaths",
|
|
52
|
+
"TestContextRepresentationBoundary"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"darwin/arm64": {
|
|
56
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
57
|
+
"workflow": ".github/workflows/ci.yml",
|
|
58
|
+
"run_id": "37242446770",
|
|
59
|
+
"binary_sha256": "3a3d61be18eba426db4f260b9cbae0d3d3c89f47efe184395d7f011cc3b4f59a",
|
|
60
|
+
"observation_sha256": "165d4cc2688867896d88ce0973b4fd0155e4214658a0af14024f8cd011868d15",
|
|
61
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
62
|
+
"native_cases": [
|
|
63
|
+
"TestContextBoundedRender",
|
|
64
|
+
"TestContextDocumentContract",
|
|
65
|
+
"TestContextMarkdownPreservation",
|
|
66
|
+
"TestContextMutationAdmission",
|
|
67
|
+
"TestContextRecoveryAndPaths",
|
|
68
|
+
"TestContextRepresentationBoundary"
|
|
69
|
+
]
|
|
70
|
+
},
|
|
71
|
+
"linux/amd64": {
|
|
72
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
73
|
+
"workflow": ".github/workflows/ci.yml",
|
|
74
|
+
"run_id": "37242446770",
|
|
75
|
+
"binary_sha256": "3b6178bb54d6a19fc56d99f8fced862ae151605a0373297a69e130d3857a8406",
|
|
76
|
+
"observation_sha256": "c561f67be64e618d90b42365c83daebc563e185bc428ce483c8199bde1dee6e1",
|
|
77
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
78
|
+
"native_cases": [
|
|
79
|
+
"TestContextBoundedRender",
|
|
80
|
+
"TestContextDocumentContract",
|
|
81
|
+
"TestContextMarkdownPreservation",
|
|
82
|
+
"TestContextMutationAdmission",
|
|
83
|
+
"TestContextRecoveryAndPaths",
|
|
84
|
+
"TestContextRepresentationBoundary"
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
"linux/arm64": {
|
|
88
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
89
|
+
"workflow": ".github/workflows/ci.yml",
|
|
90
|
+
"run_id": "37242446770",
|
|
91
|
+
"binary_sha256": "a5259074098932f815f33d3e1dea98e6d9a04277d1ada958469905da67d29437",
|
|
92
|
+
"observation_sha256": "79cae85b4701dd7cf924c71e6fac603bf3a7f8422674cee2adf206629321a1cf",
|
|
93
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
94
|
+
"native_cases": [
|
|
95
|
+
"TestContextBoundedRender",
|
|
96
|
+
"TestContextDocumentContract",
|
|
97
|
+
"TestContextMarkdownPreservation",
|
|
98
|
+
"TestContextMutationAdmission",
|
|
99
|
+
"TestContextRecoveryAndPaths",
|
|
100
|
+
"TestContextRepresentationBoundary"
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
"windows/amd64": {
|
|
104
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
105
|
+
"workflow": ".github/workflows/ci.yml",
|
|
106
|
+
"run_id": "37242446770",
|
|
107
|
+
"binary_sha256": "8339c077262f861631631de49bca7cdafec5e0730b9e3676fd2db36f3c119036",
|
|
108
|
+
"observation_sha256": "83937f62110387bb614e0a0b4ad21d84179ffdad24b3de6b78cec21d80d65721",
|
|
109
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
110
|
+
"native_cases": [
|
|
111
|
+
"TestContextBoundedRender",
|
|
112
|
+
"TestContextDocumentContract",
|
|
113
|
+
"TestContextMarkdownPreservation",
|
|
114
|
+
"TestContextMutationAdmission",
|
|
115
|
+
"TestContextRecoveryAndPaths",
|
|
116
|
+
"TestContextRepresentationBoundary"
|
|
117
|
+
]
|
|
118
|
+
},
|
|
119
|
+
"windows/arm64": {
|
|
120
|
+
"source_commit": "4a578c5a31f768d4e8437adba31e876687c6fe4e",
|
|
121
|
+
"workflow": ".github/workflows/ci.yml",
|
|
122
|
+
"run_id": "37242446770",
|
|
123
|
+
"binary_sha256": "f7b193cf0d1eb9ecd233bf1588f6290c2fb8bc41ad327918a740beb2099f719c",
|
|
124
|
+
"observation_sha256": "7d46e9b33eb4ddd2062b6c1405d5d2679b5be796596e4f3883c530df084cb085",
|
|
125
|
+
"module_sha256": "d5cccd13647e2c3a2a752b94b34dec4d4fc6aec5ced8fb0abce6ec9346ba1a7e",
|
|
126
|
+
"native_cases": [
|
|
127
|
+
"TestContextBoundedRender",
|
|
128
|
+
"TestContextDocumentContract",
|
|
129
|
+
"TestContextMarkdownPreservation",
|
|
130
|
+
"TestContextMutationAdmission",
|
|
131
|
+
"TestContextRecoveryAndPaths",
|
|
132
|
+
"TestContextRepresentationBoundary"
|
|
133
|
+
]
|
|
134
|
+
}
|
|
37
135
|
}
|
|
38
136
|
}
|
|
@@ -127,26 +127,110 @@ def marker_root(payload=None):
|
|
|
127
127
|
return get_host().marker_root(payload)
|
|
128
128
|
|
|
129
129
|
ARBITER_RE = re.compile(r"^\s*arbiter:\s*enabled\s*$", re.I)
|
|
130
|
+
_BODY_MARKER_RE = re.compile(r"^\s*<!--\s*INITIALIZED\s*-->\s*$")
|
|
131
|
+
_FENCE_RE = re.compile(r"^ {0,3}(`{3,}|~{3,})(?:[^`~].*)?$")
|
|
130
132
|
|
|
131
|
-
def
|
|
132
|
-
"""(enabled, malformed)
|
|
133
|
-
Split out so the #159 Write/Edit guard can vet the RESULTING content of an
|
|
134
|
-
edit — 'does this edit keep the repo arbiter-enabled?' — without going to
|
|
135
|
-
disk, sharing one parser with the on-disk activation check so the two never
|
|
136
|
-
disagree on what 'enabled' means."""
|
|
133
|
+
def context_state_text(text):
|
|
134
|
+
"""Return (enabled, malformed, initialized) from one CONTEXT.md parse."""
|
|
137
135
|
lines = (text or "").split("\n")
|
|
138
136
|
if not lines:
|
|
139
|
-
return (False, False)
|
|
137
|
+
return (False, False, False)
|
|
140
138
|
first = lines[0].lstrip("") # tolerate a leading UTF-8 BOM
|
|
141
139
|
if first.strip() != "---":
|
|
142
|
-
return (False, False
|
|
143
|
-
|
|
144
|
-
|
|
140
|
+
return (False, False, False)
|
|
141
|
+
enabled = False
|
|
142
|
+
body_start = None
|
|
143
|
+
for index, ln in enumerate(lines[1:], 1):
|
|
145
144
|
if ln.strip() == "---":
|
|
146
|
-
|
|
145
|
+
body_start = index + 1
|
|
146
|
+
break
|
|
147
147
|
if ARBITER_RE.match(ln):
|
|
148
|
-
|
|
149
|
-
|
|
148
|
+
enabled = True
|
|
149
|
+
if body_start is None:
|
|
150
|
+
return (False, True, False)
|
|
151
|
+
if not enabled:
|
|
152
|
+
return (False, False, False)
|
|
153
|
+
|
|
154
|
+
fence_char = ""
|
|
155
|
+
fence_length = 0
|
|
156
|
+
in_comment = False
|
|
157
|
+
for ln in lines[body_start:]:
|
|
158
|
+
stripped = ln.strip()
|
|
159
|
+
if fence_char:
|
|
160
|
+
if re.fullmatch(r" {0,3}" + re.escape(fence_char) +
|
|
161
|
+
"{" + str(fence_length) + r",}\s*", ln):
|
|
162
|
+
fence_char = ""
|
|
163
|
+
continue
|
|
164
|
+
if in_comment:
|
|
165
|
+
if "-->" in ln:
|
|
166
|
+
in_comment = False
|
|
167
|
+
continue
|
|
168
|
+
fence = _FENCE_RE.match(ln)
|
|
169
|
+
if fence:
|
|
170
|
+
fence_char, fence_length = fence.group(1)[0], len(fence.group(1))
|
|
171
|
+
continue
|
|
172
|
+
if _BODY_MARKER_RE.fullmatch(ln):
|
|
173
|
+
return (True, False, True)
|
|
174
|
+
if "<!--" in stripped and "-->" not in stripped:
|
|
175
|
+
in_comment = True
|
|
176
|
+
return (True, False, False)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def frontmatter_enabled_text(text):
|
|
180
|
+
"""(enabled, malformed) for CONTEXT.md content; shared with body parsing."""
|
|
181
|
+
enabled, malformed, _initialized = context_state_text(text)
|
|
182
|
+
return (enabled, malformed)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def initialized_body_text(text):
|
|
186
|
+
"""True only for a standalone marker in an enabled CONTEXT.md body."""
|
|
187
|
+
return context_state_text(text)[2]
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def passive_activation_inventory(root):
|
|
191
|
+
"""Read only the explicit root's activation marker; execute no project tools.
|
|
192
|
+
|
|
193
|
+
This is a pre-session inspection result, not proof of repository identity,
|
|
194
|
+
host capability, network policy, or permission to activate. The caller must
|
|
195
|
+
inventory sensitive paths before sending any source to a model.
|
|
196
|
+
"""
|
|
197
|
+
root = os.path.abspath(root)
|
|
198
|
+
if not os.path.isdir(root) or os.path.islink(root):
|
|
199
|
+
raise ValueError("passive inspection requires an existing, non-link directory")
|
|
200
|
+
state_dir = os.path.join(root, ".codearbiter")
|
|
201
|
+
ctx = os.path.join(state_dir, "CONTEXT.md")
|
|
202
|
+
if os.path.islink(state_dir) or os.path.islink(ctx):
|
|
203
|
+
raise ValueError("passive inspection refuses linked context paths")
|
|
204
|
+
if os.path.lexists(state_dir) and not os.path.isdir(state_dir):
|
|
205
|
+
raise ValueError(".codearbiter is not a directory")
|
|
206
|
+
if os.path.lexists(ctx) and not os.path.isfile(ctx):
|
|
207
|
+
raise ValueError("CONTEXT.md is not a regular file")
|
|
208
|
+
exists = os.path.isfile(ctx)
|
|
209
|
+
enabled = malformed = initialized = False
|
|
210
|
+
if exists:
|
|
211
|
+
if os.path.getsize(ctx) > 1024 * 1024:
|
|
212
|
+
raise ValueError("CONTEXT.md exceeds passive inspection read limit")
|
|
213
|
+
with open(ctx, encoding="utf-8") as stream:
|
|
214
|
+
enabled, malformed, initialized = context_state_text(stream.read(1024 * 1024 + 1))
|
|
215
|
+
effect = {"capability": "unverified", "authorization": "not_established",
|
|
216
|
+
"performed": False}
|
|
217
|
+
activation_behaviors = {
|
|
218
|
+
"git_hooks_exclusions": "scaffold may write Git-local exclusions and hooks; active startup may refresh hooks",
|
|
219
|
+
"git_fetch": "active startup may spawn detached Git fetch",
|
|
220
|
+
"update_refresh": "active startup may spawn detached update refresh",
|
|
221
|
+
"inference_transport": "host-selected model may receive approved source after authorization",
|
|
222
|
+
}
|
|
223
|
+
return {
|
|
224
|
+
"profile": "passive-before-activation",
|
|
225
|
+
"root": root,
|
|
226
|
+
"root_identity": "caller_supplied_unverified",
|
|
227
|
+
"context": {"exists": exists, "enabled": enabled,
|
|
228
|
+
"initialized": initialized, "malformed": malformed},
|
|
229
|
+
"effects": {name: {**effect, "activation_behavior": behavior}
|
|
230
|
+
for name, behavior in activation_behaviors.items()},
|
|
231
|
+
"source_reads": "none",
|
|
232
|
+
"sensitive_path_inventory": "pending",
|
|
233
|
+
}
|
|
150
234
|
|
|
151
235
|
|
|
152
236
|
def frontmatter_enabled(ctx_path):
|
|
@@ -52,6 +52,7 @@ import re
|
|
|
52
52
|
# exactly like a failure to import `os` would. No circularity risk: _modelib
|
|
53
53
|
# imports _activationlib and _hooklib, neither of which imports this module.
|
|
54
54
|
from _modelib import current_mode as _modelib_current_mode
|
|
55
|
+
from _activationlib import frontmatter_enabled_text as _activation_enabled_text
|
|
55
56
|
|
|
56
57
|
# mtime-keyed memo: statusline.py is a short-lived subprocess, but a single render
|
|
57
58
|
# can resolve arbiter_state more than once (safe() probes), and the StopHook fires
|
|
@@ -143,14 +144,18 @@ def _arbiter_enabled(ctx_path, frontmatter_enabled=None, ctx_text=None):
|
|
|
143
144
|
When `ctx_text` is supplied (performance-003: the caller already read
|
|
144
145
|
CONTEXT.md), the decision is made from that text — no re-read of ctx_path."""
|
|
145
146
|
if ctx_text is not None:
|
|
146
|
-
return
|
|
147
|
+
return _activation_enabled_text(ctx_text)[0]
|
|
147
148
|
if frontmatter_enabled is not None:
|
|
148
149
|
try:
|
|
149
150
|
enabled, _malformed = frontmatter_enabled(ctx_path)
|
|
150
151
|
return enabled
|
|
151
152
|
except Exception: # noqa: BLE001 — degrade to the local parser, never crash
|
|
152
153
|
pass
|
|
153
|
-
|
|
154
|
+
try:
|
|
155
|
+
with open(ctx_path, encoding="utf-8-sig", errors="replace") as handle:
|
|
156
|
+
return _activation_enabled_text(handle.read())[0]
|
|
157
|
+
except OSError:
|
|
158
|
+
return False
|
|
154
159
|
|
|
155
160
|
|
|
156
161
|
def arbiter_state(root, count_in_flight=None, read_board=None, frontmatter_enabled=None,
|