Thank you Phroi. This is a very sharp reading of the current design, and I think you are pointing at precisely the right boundary.
Reading the NIP again, I think it captures something quite fundamental about CKB composability. The problem is not merely “how do we add another script?” The deeper question is: where does a constraint live, when is it invoked, what surface of the transaction does it observe, which cells does it actually protect, and what is merely assumed by the surrounding builder or wallet?
That is the distinction I would like CellScript to preserve rather than smooth over.
I would say the three paths you identified are all real, but they live at different levels of maturity.
Today, the default and most honest path is to compose around existing cells.
If protocol A already occupies a cell’s type script slot, CellScript should not pretend that protocol B can simply attach another independent type rule to the same cell. Unless A was explicitly designed for that extension, B should usually build around A through receipts, proofs, companion cells, read-only CellDep / read_ref access, explicit witness requirements, and transaction-level constraints.
That is also how I read the NIP: not merely as a concrete mechanism proposal, but as a useful articulation of the slot and coverage problem in the CKB model.
This also matches some examples I have heard from @matt_ckb. Some developers seem to want lock scripts to assert conditions when they are attached to a cell. Others move authorization-like logic into the type script, as in rental-style designs. In UDT-like protocols, many state-transition assertions naturally live in the type script, while authorization stays in the lock; but there are also cases where people want the lock to act covenant-style and check transaction-wide output conditions.
To me, these are not isolated design oddities. They are all symptoms of the same deeper question: CKB protocols increasingly need a clearer vocabulary for different constraint categories — authorization constraints, attachment-time invariants, transaction-wide covenant constraints, type-local state-transition rules, and inter-protocol composition constraints.
The NIP’s output-lock-validation direction is highly relevant, but I would treat it with some care.
It may give us another place to express covenant-like constraints, especially where the type slot is already occupied. But I would be cautious about presenting this as if lock and type scripts were interchangeable. They are not. Their invocation conditions, coverage, and social meaning in the model are different.
For CellScript, the important thing is to make that difference inspectable:
- what is checked by the type script;
- what is checked by the lock script;
- whether the check applies to inputs, outputs, or the whole transaction shape;
- which cells are actually protected;
- what remains only a builder, wallet, or protocol assumption.
This is exactly the kind of boundary I would like CellScript metadata and ProofPlan to surface. CellScript should first model those constraint categories explicitly, and only then lower them into lock scripts, type scripts, wrappers, receipts, companion cells, or future L1 mechanisms such as output-lock validation, depending on the target profile and the available semantics.
On the roadmap side, I should probably phrase the v0.14 “script composition” item more carefully.
The wording may have made it sound broader than I intended. Spawn/IPC is real and useful, but I do not see it as the default answer to protocol composability. It is better understood as bounded verifier composition: delegated verification, reusable verifier modules, and modular validation pipelines. It does not make a cell’s type script slot multi-tenant, and it should not be presented as doing so.
The more important semantic layer is really v0.15, where the roadmap moves into scoped invariants and Covenant ProofPlan. That is where CellScript should make trigger, scope, reads, coverage, on-chain enforcement, and builder assumptions explicit.
So the intended layering is:
- v0.14: low-level mechanism for bounded verifier composition;
- v0.15: semantic composability through scoped invariants and ProofPlan;
- later: combine this with receipts, companion cells, read-only deps, and lock-side or output-lock validation patterns where the coverage is clear.
That distinction may not have been clear enough in the roadmap wording, so this is useful feedback.
In that sense, I see the NIP less as a separate concern and more as one of the clearest examples of why CellScript needs to exist. A good language layer should not make the underlying model disappear. It should give developers better instruments for seeing where the model’s real boundaries are.