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
50 changes: 45 additions & 5 deletions docs/completeness.md
Original file line number Diff line number Diff line change
Expand Up @@ -1161,7 +1161,9 @@ python3 internal/completeness/generate_tools153.py \
python3 internal/completeness/generate_tools156.py \
/tmp/schema-tools153.pb.gz /tmp/schema-tools156.pb.gz
python3 internal/completeness/generate_config157.py \
/tmp/schema-tools156.pb.gz internal/completeness/schema.pb.gz
/tmp/schema-tools156.pb.gz /tmp/schema-runtime157.pb.gz
python3 internal/completeness/generate_planexecute157.py \
/tmp/schema-runtime157.pb.gz internal/completeness/schema.pb.gz
```

This authenticates the prior inputs, all 380 records in the 1.4.6 snapshot,
Expand All @@ -1171,7 +1173,8 @@ exactly six additions over the intermediate 1.4.5 bundle, then only the Finish
message over that 1.4.6 bundle, then the subagent state additions, the two 1.4.9
fields and their import, the parent messages field, the config150 and config152
model declarations, the single tools153 field, the single tools156 enum value,
and the runtime157 template-map field and entry. The tests also reproduce
the runtime157 template-map field and entry, and the planexecute157 field and
message. The tests also reproduce
the embedded bundle.
The [native qualification report](compatibility/agy-1.4.6-compaction.md)
records the observed attachment representations and configuration values.
Expand Down Expand Up @@ -1477,13 +1480,50 @@ and executor metadata. Its entries get the same strict pre-decoding wire
checks as the earlier qualified maps; duplicate keys and unknown entry members
cannot disappear during decoding. No source-only rule changed.

The current compressed bundle is 138,560 bytes, SHA-256
The `runtime157` intermediate compressed bundle is 138,560 bytes, SHA-256
`2ce6f4cebef928bca35f94365bf9abaf14067fc9ab841bf6eed2d001b58f25ab`;
its decompressed descriptor SHA-256 is
`e603b335cff88609a63b131cf92491c8af64f9c402e8282d967b060d61a6336a`.
The final command in the overlay chain above reproduces this bundle:
The final commands in the overlay chain above reproduce the current bundle:

```sh
python3 internal/completeness/generate_config157.py \
/tmp/schema-tools156.pb.gz internal/completeness/schema.pb.gz
/tmp/schema-tools156.pb.gz /tmp/schema-runtime157.pb.gz
python3 internal/completeness/generate_planexecute157.py \
/tmp/schema-runtime157.pb.gz internal/completeness/schema.pb.gz
```

### Plan/execute planner configuration

The `planexecute157` profile extension retains `CascadePlannerConfig` field 60
`plan_execute_config` and its `PlanExecuteConfig` message, copied from the
same authenticated agy 1.5.7 closure as `runtime157`. The nested optional
`execution_model` enum uses the existing historical `Model` definition; no
other fields, model values or historical declarations change.

This setting can occur in both generator and executor metadata. Previously,
either occurrence stopped offline export with `unknown persisted protobuf
fields`. Both now participate in ordinary full/default comparison and remain
in offline JSON, including explicit zero-value presence. No source-only
allowance or new step projection is introduced. The profile changes so saved
attestations must be verified again.

The generator authenticates the prior uncompressed descriptor bundle with
SHA-256 `e603b335cff88609a63b131cf92491c8af64f9c402e8282d967b060d61a6336a`
and the source closure with SHA-256
`f3de51c7f2a7317d073cabcea13cd42a7f7f1adf3986c3bf5b3f07035b120d46`.
Maintenance tests reproduce the bundle and require exactly this two-declaration
addition. Synthetic SQLite tests check both metadata locations, absent and
explicit-zero execution models, full/default equality, rejection of changes
and omissions, and lossless offline export. Unknown fields, unsupported enum
values and incorrect wire types still fail closed.

A private copy of the reported native database exports both persisted steps
as JSON and Markdown after the addition. No native RPC comparison was available
because daemon discovery failed during this investigation; this result proves
offline export, not native full/default RPC qualification for the new setting.

The resulting compressed bundle is 138,615 bytes, SHA-256
`a98ccbf848a2ec82dd489484dfdbf9684c171014d366c6a1db8fbb3d41bff0ec`;
its decompressed descriptor SHA-256 is
`f05ed42c8ceb5eea6cb003f354b1fffbe8f4169cdce2a297049849624bde4680`.
2 changes: 1 addition & 1 deletion internal/cli/export_offline_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/mjacobs/agy-reader/internal/testfixture"
)

const offlineFixture = `{"cascadeId":"offline-fixture","metadata":{},"steps":[{"type":"CORTEX_STEP_TYPE_USER_INPUT","status":"CORTEX_STEP_STATUS_DONE","metadata":{},"userInput":{"userResponse":"Offline hello"}}]}`
const offlineFixture = `{"cascadeId":"offline-fixture","metadata":{},"generatorMetadata":[{"plannerConfig":{"planExecuteConfig":{"executionModel":1669}}}],"executorMetadatas":[{"cascadeConfig":{"plannerConfig":{"planExecuteConfig":{"executionModel":1669}}}}],"steps":[{"type":"CORTEX_STEP_TYPE_USER_INPUT","status":"CORTEX_STEP_STATUS_DONE","metadata":{},"userInput":{"userResponse":"Offline hello"}}]}`

func TestExportOfflineStandalone(t *testing.T) {
var requests atomic.Int32
Expand Down
6 changes: 3 additions & 3 deletions internal/completeness/config157_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ func TestTemplateOverrides157RejectsLossyMapWire(t *testing.T) {
}
}

func TestRuntime157InvalidatesPreviousAttestations(t *testing.T) {
previous := strings.TrimSuffix(Profile, "-runtime157")
func TestPlanExecute157InvalidatesPreviousAttestations(t *testing.T) {
previous := strings.TrimSuffix(Profile, "-planexecute157")
if previous == Profile {
t.Fatal("runtime qualification did not advance profile")
t.Fatal("plan/execute qualification did not advance profile")
}
snapshot, _ := fixture(t)
attestation, result := snapshot.VerifyResponses([]byte(syntheticRaw), []byte(syntheticPresentation))
Expand Down
66 changes: 66 additions & 0 deletions internal/completeness/generate_planexecute157.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""Add authenticated plan/execute configuration without replacing historical definitions."""
import argparse
import gzip
import hashlib
from pathlib import Path
import tempfile

from google.protobuf import descriptor_pb2
import generate_options145 as helpers

SNAPSHOT = Path(__file__).resolve().parents[2] / "artifacts/proto-snapshots/agy-1.5.7-5df525a2d690/closure.protoset"
SNAPSHOT_HASH = "f3de51c7f2a7317d073cabcea13cd42a7f7f1adf3986c3bf5b3f07035b120d46"
BASE_HASH = "e603b335cff88609a63b131cf92491c8af64f9c402e8282d967b060d61a6336a"


def augment(base, snapshot=SNAPSHOT):
data = snapshot.read_bytes()
helpers.require(hashlib.sha256(data).hexdigest() == SNAPSHOT_HASH, "snapshot hash mismatch")
source = descriptor_pb2.FileDescriptorSet.FromString(data)
source.DiscardUnknownFields()
result = descriptor_pb2.FileDescriptorSet()
result.CopyFrom(base)
target, current = (helpers.one(bundle.file, helpers.CORTEX_FILE) for bundle in (result, source))
helpers.require((target.package, target.syntax) == (current.package, current.syntax),
"source and target file semantics differ")
planner, original = (helpers.one(file.message_type, "CascadePlannerConfig")
for file in (target, current))
field = helpers.one(original.field, "plan_execute_config")
helpers.require(field.number == 60, "unexpected plan_execute_config field number")
helpers.require(not any(f.name == field.name or f.number == field.number for f in planner.field),
"plan_execute_config already declared")
helpers.require(not any(m.name == "PlanExecuteConfig" for m in target.message_type),
"PlanExecuteConfig already declared")
target.message_type.add().CopyFrom(helpers.one(current.message_type, "PlanExecuteConfig"))
planner.field.add().CopyFrom(field)
helpers.load_pool(result)
return result


def generate(previous, output):
helpers.require(output.resolve() not in {previous.resolve(), SNAPSHOT.resolve()},
"refusing to replace an authenticated input")
data = gzip.decompress(previous.read_bytes())
helpers.require(hashlib.sha256(data).hexdigest() == BASE_HASH, "base hash mismatch")
result = augment(descriptor_pb2.FileDescriptorSet.FromString(data))
temporary = None
try:
with tempfile.NamedTemporaryFile(dir=output.parent, prefix=".schema-", delete=False) as stream:
temporary = Path(stream.name)
stream.write(gzip.compress(result.SerializeToString(deterministic=True), mtime=0))
temporary.chmod(0o644)
temporary.replace(output)
finally:
if temporary is not None:
temporary.unlink(missing_ok=True)


if __name__ == "__main__":
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("previous", type=Path)
parser.add_argument("output", type=Path)
args = parser.parse_args()
try:
generate(args.previous, args.output)
except (ValueError, OSError) as error:
parser.exit(1, f"refused: {error}\n")
84 changes: 84 additions & 0 deletions internal/completeness/planexecute157_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package completeness

import (
"bytes"
"encoding/json"
"fmt"
"path/filepath"
"strings"
"testing"

"github.com/mjacobs/agy-reader/internal/testfixture"
)

func TestPlanExecute157RetainedAndCompared(t *testing.T) {
for _, config := range []string{`{}`, `{"executionModel":0}`, `{"executionModel":235}`} {
for _, metadata := range []string{
`"generatorMetadata":[{"plannerConfig":{"planExecuteConfig":%s}}]`,
`"executorMetadatas":[{"cascadeConfig":{"plannerConfig":{"planExecuteConfig":%s}}}]`,
} {
raw := `{"cascadeId":"fixture","metadata":{},` + fmt.Sprintf(metadata, config) + `,"steps":[]}`
path := filepath.Join(t.TempDir(), "source.db")
testfixture.Source(t, path, []byte(raw))
s, err := ReadSnapshot(t.Context(), path)
if err != nil {
t.Fatal(err)
}
if a, r := s.VerifyResponses([]byte(raw), []byte(raw)); r.State != Verified || len(a.SourceOnly) != 0 {
t.Fatalf("configuration did not compare normally: %+v", r)
}
changes := []string{
strings.Replace(raw, `"planExecuteConfig":`+config, `"planExecuteConfig":{"executionModel":269}`, 1),
strings.Replace(raw, `{"planExecuteConfig":`+config+`}`, `{}`, 1),
}
if config != `{}` {
changes = append(changes, strings.Replace(raw, config, `{}`, 1))
}
for _, changed := range changes {
if r := s.CompareFullRaw([]byte(changed)); r.State != Incomplete {
t.Fatalf("changed configuration passed full comparison: %+v", r)
}
if r := s.ComparePresentation([]byte(changed)); r.State != Incomplete {
t.Fatalf("changed configuration passed presentation comparison: %+v", r)
}
}
exported, err := s.OfflineJSON()
if err != nil || !bytes.Contains(exported, []byte(`"planExecuteConfig"`)) {
t.Fatalf("offline export lost configuration: %v", err)
}
var fields map[string]json.RawMessage
if err := json.Unmarshal(exported, &fields); err != nil {
t.Fatal(err)
}
delete(fields, "agyReader")
offline, err := json.Marshal(fields)
if err != nil {
t.Fatal(err)
}
if r := s.CompareFullRaw(offline); r.State != Verified {
t.Fatalf("offline export changed configuration or presence: %+v", r)
}
}
}
}

func TestPlanExecute157StrictWire(t *testing.T) {
for _, value := range []uint64{0, 235, 1669} {
if _, err := decode("exa.cortex_pb.CascadePlannerConfig", bytesField(60, options145Varint(1, value)...)); err != nil {
t.Fatal(err)
}
}
for name, data := range map[string][]byte{
"unknown nested field": bytesField(60, options145Varint(99, 1)...),
"unknown model": bytesField(60, options145Varint(1, 999999)...),
"wrong nested wire": bytesField(60, bytesField(1, 'x')...),
"wrong outer wire": options145Varint(60, 1),
"unknown planner field": options145Varint(9999, 1),
} {
t.Run(name, func(t *testing.T) {
if _, err := decode("exa.cortex_pb.CascadePlannerConfig", data); err == nil {
t.Fatal("unsupported configuration accepted")
}
})
}
}
4 changes: 3 additions & 1 deletion internal/completeness/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,10 @@ import (
// alternative while preserving exact historical equality when RPC retains them.
// runtime157 adds authenticated template overrides and captured task input,
// permission, cancellation, zero-iteration cron and extended swarm forms.
// planexecute157 retains the authenticated planner plan/execute configuration,
// including execution-model presence, in both generator and executor metadata.
// Every historical declaration and source-only rule remains intact.
const Profile = "sqlite-v1-format0-agy-1.3.4-5b93565c5f04-planner50-permission2-prompt23-tools143-permission1-tools144-skill1-history2-ide225-options145-compaction146-skill146-finish147-replay147-failedread146-subagents148-media149-tools149-sendmessage149-files1411-media1410-parentmsgs1410-paths1410-denied1412-cwd1412-unrun1412-config150-skill150-frontmatter150-bgcancel150-readlines150-config152-tools153-tools154-tools155-images155-tools156-retained156-legacychoices156-runtime157"
const Profile = "sqlite-v1-format0-agy-1.3.4-5b93565c5f04-planner50-permission2-prompt23-tools143-permission1-tools144-skill1-history2-ide225-options145-compaction146-skill146-finish147-replay147-failedread146-subagents148-media149-tools149-sendmessage149-files1411-media1410-parentmsgs1410-paths1410-denied1412-cwd1412-unrun1412-config150-skill150-frontmatter150-bgcancel150-readlines150-config152-tools153-tools154-tools155-images155-tools156-retained156-legacychoices156-runtime157-planexecute157"
const maxBytes = 64 << 20
const maxDepth = 100

Expand Down
Binary file modified internal/completeness/schema.pb.gz
Binary file not shown.
3 changes: 3 additions & 0 deletions scripts/test_generate_compaction146.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import sys
import tempfile
import unittest

from test_generate_planexecute157 import strip_planexecute
from unittest import mock

try:
Expand Down Expand Up @@ -57,6 +59,7 @@ def test_deterministic_exact_overlay_preserves_every_old_declaration(self):
# The committed bundle may have been compressed by another zlib version.
production = descriptor_pb2.FileDescriptorSet.FromString(gzip.decompress(
(REPO / "internal/completeness/schema.pb.gz").read_bytes()))
strip_planexecute(production)
# The later overlays have their own exact-preservation tests.
tools = generator.one(production.file, "third_party/jetski/cortex/core/tools_pb/tools.proto")
tools.message_type.remove(generator.one(tools.message_type, "Finish"))
Expand Down
3 changes: 2 additions & 1 deletion scripts/test_generate_config150.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ def test_exact_overlay_and_reproduction(self):
import generate_tools153
import generate_tools156
import generate_config157
import generate_planexecute157
augmented = generate_config152.augment(result)
previous = Path(directory) / 'config152.gz'
previous.write_bytes(gzip.compress(augmented.SerializeToString(deterministic=True), mtime=0))
intermediate = Path(directory) / "tools153.gz"
generate_tools153.generate(previous, intermediate)
generate_tools156.generate(intermediate, output)
current = descriptor_pb2.FileDescriptorSet.FromString(gzip.decompress(output.read_bytes()))
self.assertEqual(generate_config157.augment(current).SerializeToString(deterministic=True), gzip.decompress(
self.assertEqual(generate_planexecute157.augment(generate_config157.augment(current)).SerializeToString(deterministic=True), gzip.decompress(
(REPO / 'internal/completeness/schema.pb.gz').read_bytes()))
current_cortex = generator.one(current.file, generator.CORTEX_FILE)
spec = generator.one(current_cortex.message_type, 'SubagentSpec')
Expand Down
6 changes: 4 additions & 2 deletions scripts/test_generate_config157.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import tempfile
import unittest

from test_generate_planexecute157 import strip_planexecute

from test_generate_config150 import descriptor_pb2, REPO

if descriptor_pb2 is not None:
Expand All @@ -14,8 +16,8 @@
@unittest.skipIf(descriptor_pb2 is None, 'google.protobuf is not installed')
class Config157(unittest.TestCase):
def production(self):
return descriptor_pb2.FileDescriptorSet.FromString(gzip.decompress(
(REPO / 'internal/completeness/schema.pb.gz').read_bytes()))
return strip_planexecute(descriptor_pb2.FileDescriptorSet.FromString(gzip.decompress(
(REPO / 'internal/completeness/schema.pb.gz').read_bytes())))

def base(self):
result = self.production()
Expand Down
70 changes: 70 additions & 0 deletions scripts/test_generate_planexecute157.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""Authenticate the exact plan/execute delta and preserve historical definitions."""
import gzip
import hashlib
from pathlib import Path
import tempfile
import unittest

from test_generate_parentmsgs1410 import descriptor_pb2, REPO

if descriptor_pb2 is not None:
import generate_planexecute157 as generator


def strip_planexecute(bundle):
cortex = generator.helpers.one(bundle.file, generator.helpers.CORTEX_FILE)
planner = generator.helpers.one(cortex.message_type, 'CascadePlannerConfig')
planner.field.remove(generator.helpers.one(planner.field, 'plan_execute_config'))
cortex.message_type.remove(generator.helpers.one(cortex.message_type, 'PlanExecuteConfig'))
return bundle


@unittest.skipIf(descriptor_pb2 is None, 'google.protobuf is not installed')
class PlanExecute157(unittest.TestCase):
def production(self):
return descriptor_pb2.FileDescriptorSet.FromString(gzip.decompress(
(REPO / 'internal/completeness/schema.pb.gz').read_bytes()))

def base(self):
result = strip_planexecute(self.production())
self.assertEqual(hashlib.sha256(result.SerializeToString(deterministic=True)).hexdigest(), generator.BASE_HASH)
return result

def test_exact_authenticated_delta(self):
base = self.base()
result = generator.augment(base)
self.assertEqual(result, self.production())
target = generator.helpers.one(result.file, generator.helpers.CORTEX_FILE)
source = descriptor_pb2.FileDescriptorSet.FromString(generator.SNAPSHOT.read_bytes())
source.DiscardUnknownFields()
original = generator.helpers.one(source.file, generator.helpers.CORTEX_FILE)
planner = generator.helpers.one(target.message_type, 'CascadePlannerConfig')
source_planner = generator.helpers.one(original.message_type, planner.name)
field = generator.helpers.one(planner.field, 'plan_execute_config')
self.assertEqual(field, generator.helpers.one(source_planner.field, field.name))
message = generator.helpers.one(target.message_type, 'PlanExecuteConfig')
self.assertEqual(message, generator.helpers.one(original.message_type, message.name))
self.assertEqual(strip_planexecute(result), base)
with self.assertRaisesRegex(ValueError, 'already declared'):
generator.augment(self.production())

def test_generation_and_tampering(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
previous, output = root / 'previous.gz', root / 'output.gz'
previous.write_bytes(gzip.compress(self.base().SerializeToString(deterministic=True), compresslevel=1, mtime=42))
generator.generate(previous, output)
self.assertEqual(gzip.decompress(output.read_bytes()), self.production().SerializeToString(deterministic=True))
saved = output.read_bytes()
previous.write_bytes(gzip.compress(b'changed'))
with self.assertRaisesRegex(ValueError, 'base hash'):
generator.generate(previous, output)
self.assertEqual(output.read_bytes(), saved)
bad = root / 'bad.protoset'
bad.write_bytes(generator.SNAPSHOT.read_bytes() + b'changed')
with self.assertRaisesRegex(ValueError, 'snapshot hash'):
generator.augment(self.base(), bad)
self.assertEqual(output.read_bytes(), saved)
self.assertFalse(list(root.glob('.schema-*')))
with self.assertRaisesRegex(ValueError, 'authenticated input'):
generator.generate(generator.SNAPSHOT, generator.SNAPSHOT)
Loading
Loading