Workspace format
Still a folder. Now with a contract.
A workspace is any directory registered in the local registry. The layout below is canonical but not compulsory: Intralock can index a tree that contains none of it. What matters is that ownership is explicit, reserved names never overwrite user files, and generated state stays separable.
01 — Layout
The canonical tree.
The catalog, tokens, secrets, and long-lived audit ledger live outside the workspace in a private application-data directory. Only opted-in metadata and generated artifacts appear on disk inside the workspace.
my-workspace/ index.html # optional human homepage; authored regions preserved intralock.lock.html # verifiable generated snapshot AGENTS.md # agent guidance; never an authority grant manifest.yaml # optional workspace declaration README.md # ordinary authored documentation docs/ # normal user data datasets/ # normal user data applications/ # normal user data .intralock/ workspace.json # stable ID, schema, tracked root identity policy.yaml # declarative defaults and overrides generated/ # templates and static assets manifests/ # generated structured manifests receipts/ # hash-linked operation receipts revisions/ # bounded backups of generated revisions snapshots/ # reference hashes and export metadata cache/ # discardable output ignore # user-readable exclusions local/ # nonportable local-only state
index.html, AGENTS.md, .intralock/, or manifest.yaml already exists and the user has not adopted it, onboarding shows a diff and chooses non-conflicting outputs. Matching a conventional filename is never permission to overwrite.02 — Manifest
Declared intent, editable by hand.
The manifest is versioned configuration, not a database dump. Local secrets never belong in it. Precedence is explicit: operator choice overrides local protected state, which overrides the manifest, which overrides inherited policy — except that a stronger deny always wins.
schema: intralock.workspace/v1 id: wks_01JEXAMPLESTABLEID name: Example Workspace root: . indexing: enabled: true content: true follow_symlinks: false max_file_bytes: 52428800 ignores: [".git/**", "node_modules/**", "**/.env", "**/secrets/**"] views: homepage: index.html lock_snapshot: intralock.lock.html generation: preview_then_approve search: lexical: true semantic: false security: baseline: private remote_access: false mutations: approval_required capabilities: profile: local_read_only extensions: []
Validation is a first-class command
intralock manifest validate reports the exact failing line and rule, with a migration suggestion. Unknown keys are handled by schema version and strictness profile: strict mode rejects unknown security-sensitive keys; permissive import preserves them under a separate namespace without executing anything.
Precedence
- Explicit operator or session choice
- Local protected override
- Workspace manifest
- Inherited policy
- Installation default
A stronger deny always prevails over a weaker allow, regardless of level.
03 — Identity
Paths are labels. IDs are identity.
Moving a file is ordinary. Losing its history because the path changed is not. Every observed object gets a stable ID, a current canonical path, historical aliases, and an identity-confidence class.
IDs are not absolute paths. Content hashes identify versions and enable deduplication, but identical bytes do not merge two intentional objects. Filesystem-native IDs help move detection on the same volume, with the caveat that semantics differ across filesystems and backups.
A move resolver climbs a confidence ladder: persisted identity marker, then a recorded filesystem ID on the same volume, then an atomic move event correlated with prior state, then unique content hash plus temporal and structural evidence, and finally operator review.
Public references prefer intralock://workspace/{id}/object/{id} or HTTP route IDs. Path display is presentation metadata, not authority.
Symlinks and hard links
A symlink is recorded as an object with a target descriptor. Targets outside the approved workspace are not traversed without a separate allow decision. Hard links preserve distinct paths and possible shared backing — never an assumed intent.
Ambiguity
Collisions become review items with recoverable state. No silent ID reassignment, no merging on hash equality alone.
04 — Snapshot
intralock.lock.html is evidence, not a vault.
It is a versioned, digest-bound snapshot of declared and observed state. It renders without JavaScript and without the daemon. It does not grant permissions and it does not expose excluded files.
| State | Meaning |
|---|---|
| verified | Current source or ledger matches the signed snapshot. |
| stale | Snapshot is older than the declared freshness window. |
| modified | Source changed since capture; re-capture required. |
| unverifiable | Signature or key unavailable; content may still be intact. |
| invalid | Digest or signature mismatch. |
A digest covers the normalized snapshot payload, not display formatting. Signatures are optional and bind a key ID to the digest.
The snapshot may include the workspace title, snapshot ID, capture time, manifest hashes, root ID, indexed counts, representative typed relationships, capability summaries, provenance tables, data freshness, and a link to a JSON payload.
Embedded structured data uses a safely escaped, non-executable script block. Extractor output and generated descriptions are never inserted as trusted HTML.
If a user-authored intralock.lock.html already exists, generation goes to .intralock/generated/ and waits for explicit adoption.
05 — Guidance
AGENTS.md is documentation, not a credential.
It tells an authorized agent how the workspace is organized and how work is reviewed. It cannot grant access, and a machine client must still authenticate and pass policy for every operation.
Instruction documents are not executable. A command inside a README, PDF, comment, or retrieved snippet is data. It does not run because an indexer saw it or an agent asked for context. Execution uses a separate allowlisted registry, isolated runners, resource limits, and approvals.
Generated guidance lives in an owned region with round-trip parsing and delimiters. Manual text is never assumed safe to rewrite; regeneration produces a three-way diff instead of doing broad string replacement.
<!-- intralock:region start id=guidance v=1 --> ## Workspace Name: Example Workspace Root: (path withheld from public export) Schema: intralock.workspace/v1 ## Conventions - Docs: Markdown, one H1 per file - Tests: `go test ./...` from repo root - Do not rewrite files outside `.intralock/` ## Review - Propose changes with a preview diff - Destructive actions require human approval <!-- intralock:region end -->
06 — Homepages
Generate only what you adopt.
Every directory can have a virtual homepage rendered from the catalog — heading, purpose, breadcrumbs, child folders, key documents, freshness, recent changes, relationships, and actions allowed for the caller. Publishing it writes static HTML only on request.
Regeneration compares each managed region to its last generated base. Untouched regions update; edited regions return a conflict. Repeated generation from unchanged input is idempotent and carries a generator version and receipt.
Region contract
- Markers
- Explicit start/end IDs with version.
- Base hash
- Stored per region for three-way comparison.
- Conflict
- Returns a diff, never a silent rewrite.
- Escape
- File names and content escaped; scripts rejected.
- Reproduce
- Generator version + receipt on the page.