P04-01: 同時発生の更新規約

This commit is contained in:
Agent Control Runner
2026-10-18 11:16:06 +09:00
parent 20d0ae5990
commit 1b08d6b0fc
7 changed files with 377 additions and 34 deletions
@@ -0,0 +1,112 @@
{
"task_id": "P04-01",
"status": "blocked",
"checks": [
{
"kind": "py_compile",
"path": "tools/check_p04_order_evidence.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_role_fixtures.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/normal_c_join.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/normal_c_join_fixtures.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s5/run_s5_native.py",
"output": "compiled without syntax errors",
"exit_code": 0
},
{
"kind": "pure_static_ast",
"observation": "normal_c_join.verify parameters",
"output": [
"database",
"approved_database",
"candidate",
"submission",
"hashes"
]
},
{
"kind": "pure_static_source",
"observation": "checker contains runner_inputs",
"output": true
}
],
"fixtures": [
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_applicability_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_approval_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_encoder_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_join_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_native_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_negative_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_role_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_series_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/normal_c_join_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/engine_identity_negative_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py",
"execution": "unexecuted; Root only"
}
],
"engine_runs": 0,
"fixture_runs": 0,
"condition_credit": 0,
"original_completion": false
}
@@ -0,0 +1,51 @@
# REPAIR33 — blocked, no implementation or acceptance claim
P04-01 remains incomplete. Only this status and REPAIR33_STATIC_CHECKS.json
were added. Checker, fixtures, wrapper and S5 run documents remain unchanged.
No Git writes, Runner operations, fixture execution or engine runs occurred.
The instruction to return blocked for missing specifications applies to these
unresolved input contracts:
- The Root-supplied Q descriptor has no supplied schema or existing definition
in the inspected checker, S5 wrapper or local execution documentation.
`verify_roles` requires `product_binding` to contain exactly `tested_product`
and `runner_inputs`. Each runner input references an existing native receipt,
wrapper and materials; it does not define M/S fields or the wrapper's fresh-Q
configuration input. Specify the descriptor fields/types and how M, S, Q,
staged product, settings, markers, policy and material bindings are obtained
without inventing another input contract. Future hashes are not requested.
- The requested combined control includes matching Runner/Root records, but
`normal_c_join.verify(database, approved_database, candidate, submission,
hashes)` accepts only Runner databases and caller-supplied commit strings.
Its CLI has no Root exact-candidate record input or verification. Specify
that record's schema and binding, or explicitly confirm that Root performs
this join outside this verifier and define the combined control boundary.
The verifier was neither weakened nor called from the checker.
These are contract questions, not requests for permission expansion. Runner
core, Owner CLI and the reference core were not read. No dependency on them
was introduced. No speculative partial implementation was made.
Actual verification: six existing Python files compiled with py_compile;
generated bytecode was placed under the allowed execution directory and
removed. Pure AST inspection confirmed the normal_c_join parameter list;
a source assertion confirmed runner_inputs is present. Actual outputs are
recorded in REPAIR33_STATIC_CHECKS.json. All twelve discovered fixture files
are individually listed there as unexecuted; Root runs them later with its
own scratch directory. No test or acceptance result is inferred from syntax.
An initial shell here-document command failed before Python started with
`can't create temp file for here document: operation not permitted`.
It produced no verification result. The checks were then run using python3
`-c`, without shell temporary-file redirection.
Explicitly pending: this REPAIR33 implementation; S5 destruction, midnight
and exit drivers; fresh-Q plumbing for S1–S4 and the collector; all 184
executable suites and the 329 parse verifier; the truthful index; Root's
fixed run order, independent review and normal integration/final joins.
Formal 16/88, original 30/88, seven domains plus EV, all six D05 approvals
and P04 credit 0 remain fixed. M remains
`c0ea009b28a7649aca6a433a1a24dc0be5e7ab81`. No condition credit, original
completion, self-reported acceptance or cap change is claimed.
@@ -0,0 +1,95 @@
{
"task_id": "P04-01",
"status": "submitted",
"checks": [
{
"kind": "py_compile",
"path": "tools/check_p04_order_evidence.py",
"output": "tools/check_p04_order_evidence.py: py_compile completed without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py",
"output": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py: py_compile completed without syntax errors",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_role_fixtures.py",
"output": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_role_fixtures.py: py_compile completed without syntax errors",
"exit_code": 0
},
{
"kind": "ast",
"output": "AST: documentation roster is definition-only; qualifier retains identity require and structural return with provenance false; role candidate initialized, assigned and returned; pure control function has no subprocess/Git calls.",
"exit_code": 0
},
{
"kind": "py_compile",
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py",
"output": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py: py_compile completed without syntax errors (final literal inputs)",
"exit_code": 0
},
{
"kind": "ast",
"output": "AST: pure candidate controls contain four literal 40-hex inputs.",
"exit_code": 0
}
],
"fixtures": [
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_applicability_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_approval_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_candidate_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_encoder_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_join_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_native_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_negative_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_role_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/checker_series_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/normal_c_join_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/engine_identity_negative_fixtures.py",
"execution": "unexecuted; Root only"
},
{
"path": "docs/plans/original-completion-2026-10-02/execution/p04-01/s4/receipt_lifecycle_fixtures.py",
"execution": "unexecuted; Root only"
}
],
"pure_candidate_controls": "unexecuted; Root may use checker_candidate_fixtures.py --pure-only",
"engine_runs": 0,
"fixture_runs": 0,
"condition_credit": 0,
"original_completion": false
}
@@ -0,0 +1,49 @@
# REPAIR34 — structural step submitted
P04-01 remains incomplete. This step changes only the checker structural C
qualification and the two local fixture boundaries, plus this status and the
static-check record. The checker returns structure_qualified true and
provenance_verified_by_checker false with C/S/M/C_tree/Q joins. Prospective
roles return candidate_structure null. The provenance roster is documentation
only, never consumed. Other parent, tree, checker-blob and binding guards
were left unchanged.
Candidate fixtures now expect honest structural qualification for a manufactured
same-tree C. A separate --pure-only path contains three identity negatives and
one exact positive with literal 40-hex inputs; it requires no Git or engine.
The two role cases expect structural verification and separately record actual
downstream --verify-only returncode/stdout/stderr without asserting acceptance.
Both boundaries assert stderr has no 'qualification context gap'. Other
negative expectations remain unchanged. These fixtures have not been executed;
their downstream outcomes are pending Root execution, not inferred here.
Actual verification is limited to py_compile for the three changed Python
files and AST checks recorded with their real output in
REPAIR34_STATIC_CHECKS.json. Temporary compilation bytecode was created only
inside the allowed execution directory and removed. Every discovered fixture,
including the pure candidate controls, is unexecuted. An initial editing
command failed with a Python SyntaxError before any file writes; edits were
then applied in place. That command was not a validation check.
Explicitly pending in this same unit:
- normal_c_join and its fixtures: unchanged and unexecuted here; post-final
Root SQL candidate/M/S/approval/validation/review/integration/final joins
remain mandatory before original credit.
- Wrapper/descriptor: separate pre-run configuration with Root-derived M/S/Q
and pinned source/material references, not after-run binding.runner_inputs
receipts. Root JSON and exact-candidate qualification remain pending.
- S5 destruction, midnight and exit drivers; S1–S4 and collector fresh Q.
- All 184 executable suites / 329 parse verification; truthful index.
- Root run order, independent review, integration/final and provenance joins.
scratch_fixture_adapter.py routing is unchanged. No Git commands or writes,
engine runs, fixture runs, Runner operations, permissions or cap changes were
performed. Runner core and Owner CLI were not read; this step does not depend
on them. External provenance remains a required pending context, not a reason
to block the authorized structural step.
All seven domains plus EV, all six D05 approvals, formal 16/88, original 30/88
and P04 credit 0 remain fixed. Frozen M is
c0ea009b28a7649aca6a433a1a24dc0be5e7ab81. No condition credit, self-reported
acceptance, original completion or new counted unit is claimed.
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
"""Isolated candidate qualification negative; no whole-role/native credit."""
"""Candidate structure controls; no provenance or whole-role/native credit."""
import argparse
import importlib.util
import json
from pathlib import Path
@@ -11,10 +12,43 @@ sys.dont_write_bytecode = True
ROOT = Path(__file__).resolve().parents[5]
def run():
def load_gate():
spec = importlib.util.spec_from_file_location('candidate_gate', ROOT / 'tools/check_p04_order_evidence.py')
gate = importlib.util.module_from_spec(spec)
spec.loader.exec_module(gate)
return gate
def expected_candidate(commit, tree, main, submitted, composed):
return {'structure_qualified': True, 'provenance_verified_by_checker': False,
'provenance_owner': 'actual Runner.prepare_integration/integrate and Root normal_c_join AFTER final before original credit',
'join': {'C': commit, 'S': submitted, 'M': main, 'C_tree': tree, 'Q': composed}}
def run_pure():
"""Three identity negatives and one exact positive; no Git or engine."""
gate = load_gate()
commit = '1111111111111111111111111111111111111111'
tree = '2222222222222222222222222222222222222222'
submitted = '3333333333333333333333333333333333333333'
other = '4444444444444444444444444444444444444444'
for args in ((commit, other, gate.MAIN_ANCHOR, submitted, tree),
(commit, tree, other, submitted, tree),
(submitted, tree, gate.MAIN_ANCHOR, submitted, tree)):
try:
gate.qualify_normal_candidate(*args)
except ValueError as exc:
assert str(exc) == 'normal candidate identity mismatch', str(exc)
else:
raise AssertionError('invalid candidate structure qualified')
args = (commit, tree, gate.MAIN_ANCHOR, submitted, tree)
assert gate.qualify_normal_candidate(*args) == expected_candidate(*args)
return {'scope': 'pure structure only', 'negative_controls': 3,
'exact_positive_controls': 1, 'formal_acceptance': False}
def run():
gate = load_gate()
env = gate.git_environment()
env.update(GIT_AUTHOR_NAME='P04 isolated fixture', GIT_AUTHOR_EMAIL='fixture@invalid',
GIT_COMMITTER_NAME='P04 isolated fixture', GIT_COMMITTER_EMAIL='fixture@invalid')
@@ -35,16 +69,14 @@ def run():
'-m', 'synthetic C; no Root qualification')
assert git('show', '-s', '--format=%P', synthetic).split() == [main, submission]
assert git('rev-parse', synthetic + '^{tree}') == tree
try:
gate.qualify_normal_candidate(synthetic, tree, main, submission, tree)
except ValueError as exc:
assert 'qualification context gap' in str(exc), str(exc)
else:
raise AssertionError('synthetic C accepted')
return {'scope': 'isolated candidate qualification only; full role fixtures remain Root-run',
'synthetic_equal_parents_and_tree': 'rejected', 'formal_acceptance': False,
'normal_C_positive': 'unexecuted: authoritative receipt contract unavailable'}
result = gate.qualify_normal_candidate(synthetic, tree, main, submission, tree)
assert result == expected_candidate(synthetic, tree, main, submission, tree)
return {'scope': 'isolated candidate structure only; provenance remains external',
'synthetic_equal_parents_and_tree': result, 'formal_acceptance': False}
if __name__ == '__main__':
print(json.dumps(run(), indent=2))
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--pure-only', action='store_true', help='no Git, engine or scratch directory')
args = parser.parse_args()
print(json.dumps(run_pure() if args.pure_only else run(), indent=2))
@@ -52,7 +52,7 @@ def run(build, evidence):
' g.verify_roles(json.loads(Path(sys.argv[1]).read_text()),Path(sys.argv[2]))\n')
index_path = base / 'index.json'
def check(name, index=None, positive=False, full=False):
def check(name, index=None, positive=False, full=False, no_context_gap=False):
index_path.write_text(json.dumps(original if index is None else index))
if full:
directory = base / name
@@ -64,8 +64,12 @@ def run(build, evidence):
command = [sys.executable, str(probe), str(index_path), str(build)]
process_env = env
process = subprocess.run(command, cwd=checkout, env=process_env, capture_output=True, text=True)
assert (process.returncode == 0) == positive, (name, process.stdout, process.stderr)
results.append({'case': name, 'result': 'accepted' if positive else 'rejected',
if no_context_gap:
assert 'qualification context gap' not in process.stderr, (name, process.stderr)
if positive is not None:
assert (process.returncode == 0) == positive, (name, process.stdout, process.stderr)
results.append({'case': name, 'result': 'command_completed' if process.returncode == 0 else 'command_rejected',
'returncode': process.returncode, 'formal_acceptance': False,
'stdout': process.stdout, 'stderr': process.stderr})
check('real_submission_positive', positive=True)
@@ -112,12 +116,14 @@ def run(build, evidence):
changed['product_binding']['tested_product'] = git('rev-parse', anchor + '^{tree}')
check('main_tree_cannot_impersonate_Q', changed)
# A merge made by this fixture has no independent normal-C provenance.
# Equal parents/tree are insufficient, even for git merge --no-ff.
check('unqualified_merge_rejected')
# Structure qualifies; provenance and credit remain external.
check('unqualified_merge_structure', positive=True, no_context_gap=True)
check('unqualified_merge_downstream', positive=None, full=True, no_context_gap=True)
synthetic = git('commit-tree', git('rev-parse', merged + '^{tree}'),
'-p', anchor, '-p', submission, '-m', 'synthetic normal C')
git('checkout', '--detach', synthetic)
check('synthetic_identical_parents_tree_rejected')
check('synthetic_identical_parents_tree_structure', positive=True, no_context_gap=True)
check('synthetic_identical_parents_tree_downstream', positive=None, full=True, no_context_gap=True)
git('checkout', '--detach', merged)
game.unlink()
git('add', '-u')
@@ -129,7 +135,8 @@ def run(build, evidence):
changed = copy.deepcopy(original)
changed['conditions']['power_stop']['required_measurements']['charges'] = 9
check('forged_index', changed, full=True)
return {'scope': 'fixture controls only', 'results': results}
return {'scope': 'fixture controls only', 'formal_acceptance': False,
'condition_credit': 0, 'results': results}
if __name__ == '__main__':
+12 -15
View File
@@ -35,11 +35,9 @@ OWNER_BINDINGS = {
) for ref in refs
}
MAIN_ANCHOR = 'c0ea009b28a7649aca6a433a1a24dc0be5e7ab81'
# Required evidence content, not an invented Runner API. Root must supply the
# independently authoritative receipt path/hash contract before C can qualify.
# Neither an index nor a commit with matching parents/tree can supply authority.
NORMAL_C_RECEIPT_CONTRACT = None
NORMAL_C_RECEIPT_FIELDS = frozenset({
# Documentation only: external Runner prepare_integration/integrate and Root
# normal_c_join joins after final. The checker never consumes this roster.
NORMAL_C_PROVENANCE_JOIN = frozenset({
'candidate_commit', 'candidate_tree', 'first_parent', 'second_parent',
'tested_tree', 'prepare_integration_receipt', 'independent_review_receipt',
'validation_receipt', 'source_manifest_sha256', 'settings_sha256',
@@ -342,6 +340,7 @@ def verify_roles(index, directory):
"""Infer roles from Git, never from an index or a caller's stage label."""
require(not ({'candidate_commit', 'candidate_tree', 'code_only', 'candidate', 'phase'} & index.keys()),
'candidate/code-only/phase declarations are not evidence')
candidate = None
commit, actual_tree, actual = actual_checkout()
require(_GIT_ENV is not None, 'isolated object store required')
if not ancestor(MAIN_ANCHOR, commit):
@@ -369,7 +368,7 @@ def verify_roles(index, directory):
'unknown source hidden as metadata: ' + path)
if role == 'integration/final':
require(actual_tree == composed and actual == target, 'actual merge differs from composition')
qualify_normal_candidate(commit, actual_tree, main, submitted, composed)
candidate = qualify_normal_candidate(commit, actual_tree, main, submitted, composed)
require(target[CHECKER_PATH] == patch[CHECKER_PATH] == actual[CHECKER_PATH],
'checker blob differs from submission')
for path in patch:
@@ -419,25 +418,23 @@ def verify_roles(index, directory):
require(runner_paths, 'runner inputs missing')
require(index['versions'] == {'registered': REGISTERED_COMMIT, 'execution_origin': EXECUTION_ORIGIN,
'tested': tested}, 'evidence version roles')
return composed, {'role': role, 'actual_head': commit, 'actual_tree': actual_tree,
return composed, {'candidate_structure': candidate, 'role': role, 'actual_head': commit, 'actual_tree': actual_tree,
'submission': submitted, 'main': main, 'existing_metadata': metadata,
'manifest_sha256': manifest_digest(product), 'runner_paths': runner_paths,
'tested_product': tested, 'product_file_count': len(product), 'selected_file_count': len(selected_product)}
def qualify_normal_candidate(commit, tree, main, submitted, composed):
"""Fail closed until the actual Root/Runner authority contract is supplied.
"""Qualify structure only; Runner and Root verify provenance externally.
The field roster above records the required joins. It intentionally is not
a self-issued attestation format that a synthetic commit can satisfy.
The documentation roster is never consumed. Structure grants no provenance
verification or original credit.
"""
require(tree == composed and main == MAIN_ANCHOR and commit != submitted,
'normal candidate identity mismatch')
require(NORMAL_C_RECEIPT_CONTRACT is not None,
'normal C qualification context gap: authoritative Root/Runner receipt '
'path, SHA256 and provenance verification contract are not supplied')
# No authority implementation is inferred from a caller-supplied object.
raise ValueError('normal C receipt authority verifier is not implemented')
return {'structure_qualified': True, 'provenance_verified_by_checker': False,
'provenance_owner': 'actual Runner.prepare_integration/integrate and Root normal_c_join AFTER final before original credit',
'join': {'C': commit, 'S': submitted, 'M': main, 'C_tree': tree, 'Q': composed}}
def function_bytes(data):