Rocko-authored, Filbert-reviewed inspector (r6 manifest a4a44930...) with full review/build/verdict evidence under docs/plans/reviews. 43/0 selftests, oracle zero-disagreement, foundation checker PASS. Owner A9 acceptance recorded separately.
271 lines
17 KiB
Markdown
271 lines
17 KiB
Markdown
# Foundation synthetic inspector — frozen charter candidate 2
|
||
|
||
Issue: #53. Author/integrator: darkwing. Feasibility contributor: rocko.
|
||
Independent reviewer: filbert, pending exact-candidate review.
|
||
Status: proposed implementation contract, NOT permission to implement.
|
||
Jason authorized continuation of planning after accepting the reviewed map.
|
||
No source changes, migration, publication, push or live fleet activity authorized.
|
||
|
||
## 1. Bound inputs and interpretation
|
||
|
||
Accepted map/handoff: commit 7345f330fc6bfae5aa1d896c78cfb7cbe62efbae.
|
||
Source/plan baseline: d4696d09eb1b5dcf1028f30db2cd63735f51cb16.
|
||
Map verdict: FM-FILBERT-1, SHA-256
|
||
6b08c6fac0718d3db527cf9ffbfab49407e7b289d09782f5d1d0e26493eaabb3.
|
||
That approval does not cover this new charter.
|
||
|
||
Detailed incorporated specification: sections 5–13 of
|
||
reviews/2026-09-06_foundation-inspector-rocko-feasibility-r2.md,
|
||
SHA-256 f2f47fcfe22dca79f10f885b83d87a2f846fdb560425a4e20705c40ce4a123e1.
|
||
The explicit corrections/decisions below override that note. Its other sections
|
||
are contributor rationale/history, not normative repository facts. Original r1
|
||
and the FI-ROCKO-2 corrections remain history, not alternate specifications.
|
||
Any ambiguity or contradiction discovered at implementation is a charter defect
|
||
to resolve, not permission for a coder to guess or weaken refusal rules.
|
||
|
||
Candidate records.schema.json SHA-256:
|
||
05774aaf6943cb69c113e39ff1c29676a2a230ca7bf665c50dbcaa8049672af6.
|
||
Candidate check.py SHA-256:
|
||
82564a7d3200afcdda0850a9454cac6e6cd6a76687d2162c13cf214d7eac4607.
|
||
Both resolve under docs/plans/foundation-v1-candidate at d4696d09.
|
||
|
||
## 2. Deliverable and non-goals
|
||
|
||
One local CLI over an explicitly supplied synthetic bundle, with deterministic
|
||
text and JSON previews of selected agent/project/workspace permission. No cwd
|
||
inference of scope, live registry, config bootstrap, account lookup, engine launch,
|
||
assignment mutation or real permission grant. Every result, including parser/I/O
|
||
failures, says SYNTHETIC PREVIEW — NO LIVE EFFECTS and authentication: not-modelled.
|
||
|
||
Implemented operations: work.read (null target), file.read/file.change (logical
|
||
workspace-relative target), and assignment.change as a negative/unresolved check
|
||
only. The other 25 known catalog names return unsupported-capability, exit 2.
|
||
Unknown names return invalid-request, exit 2. No assignment-change success path.
|
||
No execution.stop operation is invented; the catalog contains execution.control.
|
||
No general RPC, sandbox, authentication, command audit, stopping, durability,
|
||
legacy adoption, OAuth refresh or extension integration is delivered.
|
||
|
||
Operator supplies synthetic files only. The CLI reads just that explicit input,
|
||
never discovers credentials/config. It cannot know whether arbitrary operator-
|
||
selected file bytes contain secrets before reading them; this is not a general
|
||
credential-read prevention boundary. Never pass credentials or live records to it.
|
||
Tests and agents are not authorized to access such files.
|
||
|
||
## 3. Input, identity and graph rules
|
||
|
||
Use the closed bundle/selection/registry/artifact/authorization shapes in r2 §5,
|
||
subject to the proposal and output overrides below. All fields shown there are
|
||
required except message. proposal is explicitly null outside assignment.change;
|
||
assignment.change requires non-null proposal and null operation.target. The
|
||
subjectAssignmentRef must exactly equal selection.assignmentRef; selection agent,
|
||
project and workspace must match that assignment. Never infer a different subject.
|
||
|
||
Eight supported record kinds: agent-definition, project, workspace, registration,
|
||
mission, task, assignment and decision. Other candidate kinds refuse unsupported-
|
||
kind. Candidate record shapes remain unchanged; simulation-specific fields exist
|
||
only in the enclosing bundle, never appended to accepted records.
|
||
|
||
Record references are kind/id/scope/revision, WITHOUT digest. Registry references
|
||
include registry/id/revision/digest. Artifact references and authorization IDs
|
||
match declared simulation inputs; their presence proves neither publication
|
||
permission, authentication, authentic evidence nor current real-world authority.
|
||
Decision approvals are evaluated as synthetic fixture facts, not verified signatures.
|
||
Missing declarations refuse; no flag can turn them into actual authenticated facts.
|
||
|
||
Reject duplicate record identities, duplicate registry identities even with different
|
||
digests, duplicate artifact identities (runId/artifactId) even with different digests,
|
||
and duplicate authorization IDs. Do not choose one of ambiguous registrations:
|
||
more than one current active registration for the same agent/scope refuses ambiguity.
|
||
|
||
Revision rules: complete contiguous history from 1, or a single revision-1 record.
|
||
Structural references on every revision must resolve. Apply head/current-admission
|
||
checks only to head records used for this calculation and their consulted chain;
|
||
historical records do not fail merely because their then-current refs are now old.
|
||
Explicit historical supersedes/decision subject references may name existing old
|
||
revisions. Current selected intent/task/mission/registration/delegation/proposal
|
||
refs must name heads; no invented predecessor, repair or fallback.
|
||
|
||
Cycle checks cover task.dependencies, mission.parentMissionRef and supersedes as
|
||
separate edge relations. Before tests are counted, show that each fixture reaches
|
||
the intended rule rather than failing an earlier shape error. Workspace ownership,
|
||
mission parent scope and registration parent match the accepted schema/README.
|
||
Dependencies grant no ownership/access. A selected task's same-project dependencies
|
||
must be accepted to permit file.change; another project's dependency never lends
|
||
permission. Broader dependency execution semantics are unsupported in this slice.
|
||
|
||
## 4. Mandatory policy and assignment calculation
|
||
|
||
Adopt r2 §7 L1–L9: enabled agent ceiling, both active registrations each bounded by
|
||
its mandatory scope-role ceiling, required project and workspace policy, exact
|
||
assignment/task/intent checks, applicable task/mission narrowing and an explicit
|
||
simulation execution layer. Workspace policy never falls back to a scope role.
|
||
Null optional restrictions mean no additional narrowing; missing required ceiling
|
||
never means unrestricted. Empty operations/path grants mean none. Exactly one
|
||
selected assignment contributes; no union across assignments.
|
||
|
||
Selected project/workspace must be active. Assignment is selected, belongs to the
|
||
selected agent and workspace, and binds the selected task. Task is ready/active,
|
||
with approved current plan-approval intent whose subjects include that exact task.
|
||
Assignment intent is an approved current plan-approval, delegation or assignment-
|
||
change decision covering the task/assignment. An unrelated approved acceptance
|
||
or owner-checkpoint decision is not a substitute. Mission chain must be active.
|
||
Taskless work.read/file.read skips assignment/task/mission only when assignmentRef
|
||
is explicitly null. Supplying an invalid assignment never falls back to taskless.
|
||
|
||
Paths use logical workspace roots and component-prefix intersection, never raw
|
||
string prefixes or physical filesystem traversal. Network restrictions are parsed
|
||
and intersected but no network operation is implemented or performed.
|
||
|
||
## 5. Reassignment negative check — tightened requester context
|
||
|
||
Extend r2 §5 proposal with required requesterContexts, a closed object:
|
||
- original: {assignmentRef, execution}
|
||
- target: {assignmentRef, execution}
|
||
Each assignmentRef is non-null recordRef; execution uses the same mandatory
|
||
selection.execution shape. No extra keys. Original scope derives from the subject
|
||
assignment; target scope derives from targetTaskRef. Both requester contexts belong
|
||
to requesterAgentId and the corresponding scope, not the subject agent.
|
||
|
||
Apply L1–L9 to the requester in BOTH scopes for assignment.change, using those
|
||
contexts. Role membership alone is insufficient; task/mission/intent and execution
|
||
limits also narrow the request. Require original subject and target task current
|
||
intent/status checks. Apply r2 §8 recipient/subject-bounded delegation and recorded
|
||
change checks, with approved outcomes and exact current references. Artifact basis
|
||
is evidence only. Unmodelled delegation chains refuse unsupported-capability.
|
||
|
||
No message authorizes a change. Missing delegation with a message yields the
|
||
message-is-not-authority rule once structural validation succeeds. Other failures
|
||
use fixed deterministic original-scope, target-scope, delegation, change, intent
|
||
ordering. If all simulation checks pass, return unresolved/unknown-effects with
|
||
runtime-reconciliation-required, NOT allowed. No supplied runtime observations
|
||
field exists. Echo the original selection unchanged on every admitted proposal.
|
||
This is a negative preview, not a real assignment engine or proof of stopping.
|
||
|
||
## 6. Canonicalization and precise limits
|
||
|
||
Adopt separately named inspector-content-digest/1 for mock registry content only:
|
||
sorted keys, compact encoding, ASCII string domain, safe integer values, array order
|
||
preserved. No launch fingerprint or full JCS claim. V1–V3 in r2 were independently
|
||
recomputed and match. Use 1.5 (not 1.0) for the nonintegral-number V4 test: JavaScript
|
||
cannot distinguish numeric 1.0 from 1 after parsing. Reject negative zero and unsafe
|
||
integer values. Strict bundle number tokens use integer notation only: reject
|
||
fraction/exponent forms and negative zero, bound integer tokens exactly before
|
||
Number conversion. This prevents precision loss from hiding unsupported values.
|
||
This lexical restriction is an inspector profile rule, not a change to candidate
|
||
JSON Schema integer semantics; the differential record validator tests shapes
|
||
separately from this strict-input profile.
|
||
Non-ASCII mock content refuses unsupported-capability; candidate record and target
|
||
paths still use the candidate Unicode/path formats. Validation tests separate schema
|
||
validity from the stricter inspector input/canonicalization domain.
|
||
|
||
Bounds: file <=1 MiB; each top-level inventory <=256; arrays <=1024; nesting <=32;
|
||
strings <=4096 UTF-8 bytes subject to stricter candidate limits. Duplicate JSON keys,
|
||
malformed UTF-8, invalid calendar dates, forbidden path characters/segments and
|
||
unknown fields refuse. Parser object construction must not invoke prototype setters;
|
||
__proto__/constructor keys are ordinary unknown keys, never executable behavior.
|
||
Never normalize an invalid path into a permitted one.
|
||
|
||
Linux input open: require available O_RDONLY, O_NOFOLLOW and O_NONBLOCK; open the
|
||
final component without following its symlink, fstat regular type and bounded size,
|
||
read within limit with an extra-byte/truncation check, close in finally. Parent-path
|
||
containment is NOT claimed. Missing/symlink/FIFO/nonregular input refuses exit 4.
|
||
Do not OR an undefined O_CLOEXEC constant: host Node v26.8.1 exposes none (measured).
|
||
No child spawning or close-on-exec guarantee is claimed. The CLI itself never spawns;
|
||
verification harness processes are separate test effects. Same-size concurrent file
|
||
mutation is not ruled out by size checks: operator/test inputs must remain quiescent.
|
||
|
||
## 7. Output and exits — replaces r2 §9 shape
|
||
|
||
Closed result fields, emitted on every outcome:
|
||
- disclaimer: fixed SYNTHETIC PREVIEW — NO LIVE EFFECTS
|
||
- preview: fixed preview: no live registrations or permission grants
|
||
- bundleVersion: 1
|
||
- authentication: fixed not-modelled
|
||
- declarations: fixed unverified-simulation
|
||
- result: allowed | refused | unresolved | invalid
|
||
- reason: allowed | invalid-request | missing-state | stale-revision |
|
||
not-authorized | unsupported-capability | unsupported-kind | unknown-effects | io-failure
|
||
- rule: fixed documented rule identifier or null; never input-derived prose
|
||
- selection: null before safe structural validation, otherwise exactly the selected
|
||
{agentId, projectId, workspaceId, assignmentRef} supplied by the caller
|
||
- operation: null before safe validation, otherwise the validated {name, target}
|
||
- proposal: null outside a valid assignment.change input, otherwise
|
||
{result, reason, rule, selectedAssignmentRef}, with no allowed result
|
||
- diagnostic: null or {byteOffset, inputPath}, each member nullable; offset only for
|
||
parse failure, original argv path only for I/O failure, never file contents
|
||
|
||
No consulted inventory, global counts, unrelated identities/payloads or raw parser
|
||
messages. Text and JSON derive from the same result. JSON is ordinary valid JSON
|
||
with the disclaimer field, not a non-JSON preamble. Text escapes control characters
|
||
in echoed arguments/targets so diagnostics cannot inject terminal controls.
|
||
No time/random data. No output claims authentic publication or real grants.
|
||
|
||
Exits: 0 permitted permission preview; 2 malformed/structurally incoherent or
|
||
unsupported input; 3 simulated permission refusal or unresolved admission; 4 I/O.
|
||
Missing required JSON keys (including execution) are structural: 2 invalid-request.
|
||
Absent referenced ordinary records are incoherent: 2 missing-state. Absent declared
|
||
mandatory policy/artifact/authorization inputs: 3 missing-state. Existing historical
|
||
reference used for current admission: 3 stale-revision. Cycles/duplicates: 2 invalid-
|
||
request. These override inconsistent example exits in r2. Refusal is never repaired.
|
||
|
||
## 8. Physical paths, toolchain and verification
|
||
|
||
Proposed implementation allowlist only:
|
||
- scripts/foundation-inspect.mjs (CLI; eventual packages/mosaic)
|
||
- scripts/foundation/{strict-json,canonical,resolve}.mjs (pure; eventual packages/config)
|
||
- scripts/foundation/validate-record.mjs (test-only differential bridge)
|
||
- scripts/foundation/verify-schema.py (verification only)
|
||
- scripts/foundation/*.test.mjs and scripts/foundation/fixtures/**
|
||
- scripts/test-foundation.sh
|
||
|
||
This is not yet a code-write authorization. No root/package-manager files, packages/
|
||
scaffolds, duplicate runtime sources, .pi/extensions, Dewey scripts, roles or config
|
||
changes. Pure modules never import live config, filesystem/process/network APIs or
|
||
read environment/clock. CLI handles input/output only, with no ambient config lookup.
|
||
|
||
Node ESM, zero new runtime dependencies. Record exact tested Node version; proposed
|
||
minimum 22 is not evidence of testing every supported version. Host measured 26.8.1;
|
||
container source uses node:24-bookworm-slim, not the first CLI's test environment.
|
||
No new repository engines pin is inferred. No automatic installation.
|
||
|
||
Mandatory verification uses existing explicitly selected Python/jsonschema 4.26.0,
|
||
checking pinned schema/checker hashes first. Missing dependency fails, never skips.
|
||
The differential bridge compares field-level validation over supported candidate
|
||
fixtures plus deterministic mutations, not invocation of check.py as a library.
|
||
Keep record-schema verdict distinct from unsupported-kind/profile/graph refusal.
|
||
Use calendar/path format semantics from the pinned checker, not string-only tests.
|
||
|
||
Unit/CLI tests cover r2 §12 with these overrides. Separate observed fixture/home/cwd/
|
||
data-root roots from harness output. Compare before/after path/type/size/mode/owner/
|
||
inode/content inventories; canaries and static import checks are bounded evidence,
|
||
not a sandbox or proof of no reads. No native synchronization or live fleet tests.
|
||
Required five repository suites and foundation author checks must remain green.
|
||
|
||
## 9. Acceptance and gates
|
||
|
||
A1. Positive read and assigned file.change permission previews with coherent records;
|
||
deterministic text/JSON, explicit disclaimers and no effects.
|
||
A2. Unregistered second workspace/cross-project selection refuses without fallback
|
||
or unrelated payload disclosure.
|
||
A3. Ownership/reference/duplicate/revision/cycle negatives hit the intended rules.
|
||
A4. Required role ceilings and all applicable layers narrow; empty/missing authority,
|
||
cross-assignment union and unassigned change refuse.
|
||
A5. Encoding, duplicate keys, calendar, path, bounds and unknown-field tests refuse
|
||
safely with the documented schema/profile distinction.
|
||
A6. Input/observed roots unchanged; no bootstrap, ambient config/credential lookup,
|
||
engine, network, installation or migration action.
|
||
A7. Cross-lane proposal preserves original selection; requester limits in both
|
||
scopes enforced; even fully supplied mock evidence cannot yield allowed.
|
||
A8. All output/exit combinations match the closed result contract, including parse
|
||
and I/O failure. No raw contents, unrelated metadata or terminal injection.
|
||
A9. Jason runs the positive and negative demo and understands the limitation before
|
||
any dependent live-registry/runtime increment begins.
|
||
|
||
First: Filbert independently reviews the frozen charter and incorporated note at
|
||
exact hashes without authorship or edits. Resolve substantive findings as a new
|
||
candidate. Then present the reviewed build scope to Jason for implementation
|
||
approval; prior map acceptance does not supply it. After authorized implementation,
|
||
retain separate author/reviewer roles, serialize shared index use, run all required
|
||
checks and obtain owner demo acceptance before dependent work. No automatic push,
|
||
issue closure, implementation or next-phase advancement follows from this charter.
|